Adam Jones
Adam Jones

Reputation: 2460

How do I sign an email message with a certificate and private key?

So I'm trying to sign an email using an X509Certificate2 that has been selected by a user. I've been trying to do this using MimeKit but the documentation for this appears to be old.

This is how they tell you to do this on the github page (found here)

using (var ctx = new MySecureMimeContext ()) {
    var certificate = GetJoeysX509Certificate ();
    var signer = new CmsSigner (certificate);
    signer.DigestAlgorithm = DigestAlgorithm.Sha1;

    message.Body = MultipartSigned.Create (ctx, signer, body);
}

The first issue I have is that the above is using

Org.BouncyCastle.X509.X509Certificate 

and I am getting the certificate from X509Store() which uses

System.Security.Cryptography.X509Certificates.X509Certificate2

i.e.

X509Store store = new X509Store("My");

store.Open(OpenFlags.ReadOnly);

// bind to dropdownlist for user to select...

store.Close();

This suggests that I should be retrieving my list of certificates using some other method (one that I haven't been able to find any documentation for).

My second problem is that, CmsSigner requires a second argument (AsymmetricKeyParameter), not one, as shown in the example.

So my questions are:

Upvotes: 0

Views: 935

Answers (1)

jstedfast
jstedfast

Reputation: 38528

To get an Org.BouncyCastle.X509.X509Certificate from a System.Security.Cryptography.X509Certificates.X509Certificate2, you can use the following code snippet:

static bool TryGetCertificateAndPrivateKey (X509Certificate2 x509Certificate2, out Org.BouncyCastle.X509.X509Certificate certificate, out AsymmetricKeyParameter privateKey)
{
    if (x509Certificate2 == null || !x509Certificate.HasPrivateKey) {
        certificate = null;
        privateKey = null;
        return false;
    }

    var keyPair = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair (x509Certificate2.PrivateKey);
    certificate = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate (x509Certificate2);
    privateKey = keyPair.Private;

    return true;
}

I'll add a new CmsSigner constructor that takes an X509Certificate2 that does the conversion for you in the next release of MimeKit.

Upvotes: 2

Related Questions