Search code examples
c#streamprivate-keymailkitdkim

Use Stream to read private key


UPDATE WITH A READER for more inside:

This works:

var privateKeyPath = @"C:\foo\DKIM Private Key.txt";
var signer = new DkimSigner(
    privateKeyPath, 
    mailKitConfiguration.Domain, 
    mailKitConfiguration.Selector);
signer.Sign(message, headersToSign);
    

How can it work using Stream instead? - I don't even know if it's my privateKey variable or my memory Stream that is causing my troubles. I've tried this:

var privateKey = @"-----BEGIN RSA PRIVATE KEY-----MICESDABCDEF..............KBgQDa3-----END RSA PRIVATE KEY-----";
var privateKeyBytes = Encoding.ASCII.GetBytes(privateKey);
using (var memory = new MemoryStream(privateKeyBytes))
{
    using (var reader = new StreamReader(memory))
    {
        var test1 = reader.ReadLine(); // test1: "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDa38lnCp4wTcuk0Dkl6zjbc9hkeTCLFa0F4pc7XCsDj......."
        var test2 = reader.ReadLine(); // test2: empty
        var test3 = reader.ReadLine(); // test3: empty
    }

    memory.Position = 0;

    var signer = new DkimSigner(
        memory, 
        mailKitConfiguration.Domain, 
        mailKitConfiguration.Selector
    );
    signer.Sign(message, headersToSign);
}

Message:

System.FormatException: Private key not found.

Stacktrace:

at MimeKit.Cryptography.DkimSignerBase.LoadPrivateKey(Stream stream)
at MimeKit.Cryptography.DkimSigner..ctor(Stream stream, String domain, String selector, 
DkimSignatureAlgorithm algorithm)

Solution

  • You don't need to reset the stream's position to 0, the constructor MemoryStream(byte[]) already starts at 0.

    You need newline characters in your key: -----BEGIN RSA PRIVATE KEY-----\r\n(data)\r\n---.