Digital Signature and E-mail Encryption/Decryption - S/MIME


Digital signature prevents email content is faked or changed in transport level. Encrypting email protects email content from exposure to inappropriate recipients. Both digital signature and email encrypting depend on digital certificate.

How to sign email content?

Digital signature is always signed by sender certificate. The certificate used to sign email content MUST have the public/private key pair. First of all, the user MUST get a digital certificate for personal email protection from third-party certificate authorities such as www.verisign.com. After the certificate is installed on the machine, it can be viewed by "Control Pannel"->"Internet Options"->"Content"->"Certificates"->"Personal". When you view the certificate, please note there is a line "You have a private key that corresponds to this certificate" in the certificate view, that means you are able to use this certificate to sign email content. If this line doesn't appear, that means you are unable to sign the email content by this certificate. To sign email content, please refer to EASendMail SMTP Component.

How to encrypt email?

Encrypting email doesn't require sender certificate but the certificate with public key for every recipient. For example, from@adminsystem.com sends an email to rcpt@adminsystem.com with digital signature. The digital signature contains the public key certificate for from@adminsystem.com, then rcpt@adminsystem.com can send an encrypted email with this certificate back to from@adminsystem.com. Only from@adminsystem can read this email, because this email MUST be decrypted by private key of from@adminsystem.com. Therefore, you MUST receive an digital signed email from other people (Most email clients such as outlook, outlook express will add the certificate to the Other People Storage automatically once an digital signed email is received) before you can send encrypted email to this people. To encrypt email, please refer to EASendMail SMTP Component.

Verify signed email and decrypt the encrypted email.

EAGetMail Mail class provides an easy way to verify the email digital signature and get the signer certificate. The signer certificate only contains the public key, that means you can add this certificate to your user certificate storage so that you can use this certificate to encrypt email and send the encrypted email back to the sender, only the sender can decrypt the email.

Example

[Visual Basic, C#] The following example demonstrates how to verify signed email and decrypt encrypted email with EAGetMail POP3 & IMAP4 Component. To get the full samples of EAGetMail, please refer to Samples section.

[Visual Basic]
Dim mail As Mail = New Mail("TryIt")
mail.Load("c:\test.eml", False)

If mail.IsEncrypted Then
    Try
            ' this email is encrypted, we decrypt it by user default certificate.
            ' you can also use specified certificate like this
            ' Dim decryptCert As New X509Certificate2("D:\mycert\test.pfx",
            '    "nosecret",
            '    X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.UserKeySet)
            ' mail.DecryptMessage(decryptCert)
        
        mail.DecryptMessage(Nothing)
    Catch ep As Exception
        MessageBox.Show(ep.Message)
    End Try
End If

If mail.IsSigned Then
    Try
        Dim signerCert As X509Certificate2 = mail.VerifyMessageSignature()
        MessageBox.Show("This email contains a valid digital signature.")

        ' You can add the certificate to your certificate storage like this
        ' Dim store As New X509Store("My", StoreLocation.CurrentUser)
        ' store.Open(OpenFlags.ReadWrite)
        ' store.Add(signerCert)
        ' store.Close()
        ' then you can use send the encrypted email back to this sender.

    Catch ep As Exception
        MessageBox.Show(ep.Message)
    End Try
End If


[C#] Mail mail = new Mail("TryIt"); mail.Load("c:\\test.eml", false); if (mail.IsEncrypted) { try { // this email is encrypted, we decrypt it by user default certificate. // you can also use specified certificate like this /* X509Certificate2 decryptCert = new X509Certificate2("D:\\mycert\\test.pfx", "nosecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.UserKeySet); mail.DecryptMessage(decryptCert); */ mail.DecryptMessage(null); } catch (Exception ep) { MessageBox.Show(ep.Message); } } if (mail.IsSigned) { try { // This email is digital signed. X509Certificate2 signerCert = mail.VerifyMessageSignature(); MessageBox.Show("This email contains a valid digital signature."); // You can add the certificate to your certificate storage like this /* X509Store store = new X509Store("My", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); store.Add(signerCert); store.Close(); */ // then you can use send the encrypted email back to this sender. } catch (Exception ep) { MessageBox.Show(ep.Message); } }

pfx and cer

*.pfx certificate contains the public/private key and *.cer only contains the public key, so *.pfx is able to decrypt email, but *.cer is used to encrypted email only. *.pfx and *.cert can be exported by "Control Pannel"->"Internet Options"->"Content"->"Certificates". If importing private key is chosen, the *.pfx will be generated, otherwise *.cer will be generated.

Decrypt E-mail in ASP.NET & Web Application

Since ASP.NET application is running under ASPNET user, it is not a normal user in Operating System. You should use Load method to load the certificate file directly instead of finding certificate in the user certificate storage. When *.pfx is loaded, X509KeyStorageFlags.MachineKeySet should be used instead of X509KeyStorageFlags.UserKeySet.

Example

[Visual Basic]
If mail.IsEncrypted Then
    Try
            
        Dim decryptCert As New X509Certificate2("D:\mycert\test.pfx",
            "nosecret",
            X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.MachineKeySet)
        mail.DecryptMessage(decryptCert)

    Catch ep As Exception
        MessageBox.Show(ep.Message)
    End Try
End If

[C#]
if (mail.IsEncrypted)
{
    try
    {
        X509Certificate2 decryptCert = new X509Certificate2("D:\\mycert\\test.pfx",
            "nosecret",
            X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
            mail.DecryptMessage(decryptCert);
    }
    catch (Exception ep)
    {
        MessageBox.Show(ep.Message);
    }
}

See Also

Using EAGetMail POP3 and IMAP4 Component
User Authentication and SSL Connection
Enable TLS 1.2 on Windows XP/2003/2008/7/2008 R2
Using Gmail IMAP4 OAUTH
Using Gmail/GSuite Service Account + IMAP4 OAUTH
Using Office365 EWS OAUTH
Using Office365 EWS OAUTH in Background Service
Using Hotmail IMAP4 OAUTH
Unique Identifier (UIDL) in POP3 and IMAP4 protocol
Parse Bounced Email (delivery-report)
Work with winmail.dat (TNEF Parser)
EAGetMail Namespace References
EAGetMail POP3 and IMAP4 Component Samples

Online Tutorials

Verify Digital Signature and Decrypt Email in C# - Tutorial
Verify Digital Signature and Decrypt Email in VB.NET - Tutorial
Verify Digital Signature and Decrypt Email in C++/CLI - Tutorial