Digital Signature and E-mail Encryption (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 with digital signature?

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 with EASendMail, the certificate with private key is required to be imported to SmtpMail.From.Certificate properly.

c# sign email with certificate

Example

[Visual Basic, C#] The following example demonstrates how to load certificate to sign email content with EASendMail SMTP Component. To get the full samples of EASendMail, please refer to Samples section.

[VB - Sign Email with Certificate]

Try
    Dim oMail As SmtpMail = New SmtpMail("TryIt")
    oMail.From = New MailAddress("test@emailarchitect.net")

    ' Find certificate by email adddress in My Personal Store. 
    ' The certificate can be imported by *.pfx file like this: 
    ' oMail.From.Certificate.Load("c:\test.pfx", "pfxpassword", Certificate.CertificateKeyLocation.CRYPT_USER_KEYSET) 
    ' Once the certificate is loaded to From, the email content will be signed automatically

    oMail.From.Certificate.FindSubject(oMail.From.Address,
        Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER,
        "My")

Catch exp As Exception
    Console.WriteLine("No sign certificate found for sender email: {0}", exp.Message)
End Try


[C# - Sign Email with Certificate] try { SmtpMail oMail = new SmtpMail("TryIt"); oMail.From = "test@adminsystem.com"; // Find certificate by email adddress in My Personal Store. // The certificate can be also imported by *.pfx file like this: // oMail.From.Certificate.Load("c:\\test.pfx", "pfxpassword", Certificate.CertificateKeyLocation.CRYPT_USER_KEYSET); // Once the certificate is loaded to From, the email content will be signed automatically oMail.From.Certificate.FindSubject(oMail.From.Address, Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER, "My"); } catch (Exception exp) { Console.WriteLine("No sign certificate found {0}", exp.Message); }

Signature Algorithm

You can use SignatureHashAlgorithm property to set signature algorithm to MD5, SHA1, SHA256, SHA384 or SHA512.

RSASSA-PSS Signature

If you need to use RSASSA-PSS signature scheme, you need a special version of EASendMail, please have a look at this topic:
RSASSA-PSS + RSA-OAEP Encryption with SHA256

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 with EASendMail, the certificate for recipient should be loaded to MailAddress.Certificate property.

By default, Personal digital certificate is stored at Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER "my". Encryption digital certificates are stored at Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER "Address Book". If you want to search certificate in Windows Active Directory, please use Certificate.CertificateStoreLocation.CERT_STORE_PROV_LDAP_STORE and input LDAP query statement in storeName parameter.

Example

[Visual Basic, C#] The following example demonstrates how to load certificate to encrypt email with EASendMail SMTP Component. To get the full samples of EASendMail, please refer to Samples section.

[VB - Encrypt Email]

Dim oMail As SmtpMail = New SmtpMail("TryIt")
oMail.From = New MailAddress("test@adminsystem.com")
oMail.To = New AddressCollection("encrypt1@adminsystem.com, encrypt2@adminsystem.com")

For i As Integer = 0 To oMail.To.Count - 1
    Dim recipient As MailAddress = oMail.To(i)
    Try
        ' Find certificate by email adddress in My Other Peoples Store.
        ' The certificate can be imported by *.cer file like this: 
        ' recipient.Certificate.Load("c:\encrypt1.cer")
        ' Once the certificate Is loaded to MailAddress, the email content will be encrypted automatically
        recipient.Certificate.FindSubject(recipient.Address,
                Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER,
                "AddressBook")
    Catch
        Try
            ' No certificate found in AddressBook, lookup it in My 
            recipient.Certificate.FindSubject(recipient.Address,
                Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER,
                "My")
        Catch ex As Exception
            Console.WriteLine("No encryption certificate found for {0} - {1}", recipient.Address, ex.Message)
        End Try
    End Try
Next


[C# - Encrypt Email] SmtpMail oMail = new SmtpMail("TryIt"); oMail.From = "test@adminsystem.com"; oMail.To = "encrypt1@adminsystem.com, encrypt2@adminsystem.com"; for (int i = 0; i < oMail.To.Count; i++) { MailAddress recipient = oMail.To[i] as MailAddress; try { // Find certificate by email adddress in My Other Peoples Store. // The certificate can be also imported by *.cer file like this: // recipient.Certificate.Load("c:\\encrypt1.cer"); // Once the certificate is loaded to MailAddress, the email content will be encrypted automatically recipient.Certificate.FindSubject(recipient.Address, Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER, "AddressBook"); } catch { try { // No certificate found in AddressBook, lookup it in My recipient.Certificate.FindSubject(recipient.Address, Certificate.CertificateStoreLocation.CERT_SYSTEM_STORE_CURRENT_USER, "My"); } catch (Exception exp) { Console.WriteLine("No encryption certificate found for {0} - {1}", recipient.Address, exp.Message); } } }
[VB - Find Certificate in Active Directory by LDAP] Dim oMail As SmtpMail = New SmtpMail("TryIt") oMail.From = New MailAddress("test@adminsystem.com") oMail.To = New AddressCollection("Encryptor <encrypt@adminsystem.com>") For i As Integer = 0 To oMail.To.Count - 1 Dim recipient As MailAddress = oMail.To(i) Try ' Please change the ldap path as your environment. recipient.Certificate.FindSubject(recipient.Address, Certificate.CertificateStoreLocation.CERT_STORE_PROV_LDAP_STORE, String.Format("ldap:///CN={0},CN=USERS,DC=my,DC=server?userCertificate", recipient.Name)) Catch exp As Exception Console.WriteLine("No encryption certificate found for {0} - {1}", recipient.Address, exp.Message) End Try Next
[C# - Find Certificate in Active Directory by LDAP] SmtpMail oMail = new SmtpMail("TryIt"); oMail.From = "test@adminsystem.com"; oMail.To = "Encryptor <encrypt@adminsystem.com>"; for (int i = 0; i < oMail.To.Count; i++) { MailAddress recipient = oMail.To[i] as MailAddress; try { // Please change the ldap path as your environment. recipient.Certificate.FindSubject(recipient.Address, Certificate.CertificateStoreLocation.CERT_STORE_PROV_LDAP_STORE, String.Format("ldap:///CN={0},CN=USERS,DC=my,DC=server?userCertificate", recipient.Name)); } catch (Exception exp) { Console.WriteLine("No encryption certificate found for {0} - {1}", recipient.Address, exp.Message); } }

Encryption Algorithm

You can use EncryptionAlgorithm property to set encryption algorithm to RC2, RC4, 3DES, AES128 (RSAES-OAEP), AES192 (RSAES-OAEP) or AES256 (RSAES-OAEP).

RSA-OAEP Encryption with SHA256

If you need to use RSA-OAEP encryption with sha256 scheme, please have a look at this topic:
RSASSA-PSS + RSA-OAEP Encryption with SHA256

pfx and cer

*.pfx certificate contains the public/private key and *.cer only contains the public key, so *.pfx is able to sign and encrypt 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.

Sign and Encrypt 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, Certificate.CertificateKeyLocation.CRYPT_MACHINE_KEYSET should be used instead of Certificate.CertificateKeyLocation.CRYPT_USER_KEYSET.

Example

[Visual Basic]
oMail.From.Certificate.Load("c:\test.pfx", "pfxpassword", Certificate.CertificateKeyLocation.CRYPT_MACHINE_KEYSET)

[C#]
oMail.From.Certificate.Load("c:\\test.pfx", "pfxpassword", Certificate.CertificateKeyLocation.CRYPT_MACHINE_KEYSET);

Digital signed/encrypted email with EASendMail service

Please rerfer to Work with EASendMail Service (Email Queuing)

Online Examples

Sign Email - Visual Basic
Encrypt Email - Visual Basic
Sign Email - C#
Encrypt Email - C#
Sign Email - C++/CLI
Encrypt Email - C++/CLI

See Also

Using EASendMail SMTP .NET Component
User Authentication and SSL Connection
From, ReplyTo, Sender and Return-Path
DomainKeys and DKIM Signature
Send E-mail Directly (Simulating SMTP server)
Work with EASendMail Service (Email Queuing)
Bulk Email Sender Guidelines
Process Bounced Email (Non-Delivery Report) and Email Tracking
EASendMail .NET Namespace References
EASendMail SMTP Component Samples