Digital Signature and E-mail Encryption/Decryption


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 object 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 6.0, Visual C++, Delphi] The following example demonstrates how to verify signed email and decrypt encrypted email with EAGetMail POP3 & IMAP4 ActiveX Object. To get the full samples of EAGetMail, please refer to Samples section.

[Visual Basic 6.0]
Const CRYPT_MACHINE_KEYSET = 32
Const CRYPT_USER_KEYSET = 4096
Const CERT_SYSTEM_STORE_CURRENT_USER = 65536
Const CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072

Sub VerifyAndDecryptEmail()

On Error Resume Next
    Dim oMail As New EAGetMailObjLib.Mail
    oMail.LicenseCode = "TryIt"
    oMail.LoadFile "c:\test.eml", False
    If Err.Number <> 0 Then
        MsgBox Err.Description
        Exit Sub
    End If

    If (oMail.IsEncrypted) Then
            ' this email is encrypted, we decrypt it by user default certificate.
            ' you can also use specified certificate like this
            ' Dim oCert As New EAGetMailObjLib.Certificate
            ' oCert.LoadFromFile "c:\test.pfx", "pfxpassword", CRYPT_USER_KEYSET 
            ' Set oMail = oMail.Decrypt(oCert)
            Set oMail = oMail.Decrypt(Nothing)
            If Err.Number <> 0 Then
                MsgBox Err.Description
                Exit Sub
            End If
    End If

    If (oMail.IsSigned) Then
            'this email is digital signed.
            Dim oCert As EAGetMailObjLib.Certificate
            Set oCert = oMail.VerifySignature()
        
            If Err.Number <> 0 Then
                MsgBox Err.Description
                Exit Sub
            End If
            MsgBox "This email contains a valid digital signature."
            'you can add the certificate to your certificate storage like this
            'oCert.AddToStore CERT_SYSTEM_STORE_CURRENT_USER,"addressbook"
            'then you can use send the encrypted email back to this sender.        
    End If
End Sub


[VBScript] Const CRYPT_MACHINE_KEYSET = 32 Const CRYPT_USER_KEYSET = 4096 Const CERT_SYSTEM_STORE_CURRENT_USER = 65536 Const CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072 On Error Resume Next Dim oMail Set oMail = CreateObject("EAGetMailObj.Mail") oMail.LicenseCode = "TryIt" oMail.LoadFile "c:\test.eml", False If Err.Number <> 0 Then MsgBox Err.Description Exit Sub End If If (oMail.IsEncrypted) Then ' this email is encrypted, we decrypt it by user default certificate. ' you can also use specified certificate like this ' Dim oCert ' Set oCert = CreateObject("EAGetMailObj.Certificate") ' oCert.LoadFromFile "c:\test.pfx", "pfxpassword", CRYPT_USER_KEYSET ' Set oMail = oMail.Decrypt(oCert) Set oMail = oMail.Decrypt(Nothing) If Err.Number <> 0 Then MsgBox Err.Description Exit Sub End If End If If (oMail.IsSigned) Then 'this email is digital signed. Dim oCert Set oCert = oMail.VerifySignature() If Err.Number <> 0 Then MsgBox Err.Description Exit Sub End If MsgBox "This email contains a valid digital signature." 'you can add the certificate to your certificate storage like this 'oCert.AddToStore CERT_SYSTEM_STORE_CURRENT_USER,"addressbook" 'then you can use send the encrypted email back to this sender. End If
[Visual C++] #include "eagetmailobj.tlh" using namespace EAGetMailObjLib; vod VerifyAndDecryptEmail() { ::CoInitialize(NULL); try { IMailPtr oMail = NULL; oMail.CreateInstance(__uuidof(EAGetMailObjLib::Mail)); oMail->LicenseCode = _T("TryIt"); oMail->LoadFile(_T("d:\\test.eml"), VARIANT_FALSE); if(oMail->IsEncrypted == VARIANT_TRUE) { //this email is encrypted, we decrypt it by user default certificate. // you can also use specified certificate like this //ICertificatePtr oCert; //oCert.CreateInstance(__uuidof(EAGetMailObjLib::Certificate)); //oCert->LoadFromFile(_T("c:\\test.pfx"), _T("pfxpassword"), CRYPT_USER_KEYSET); //oMail = oMail->Decrypt(oCert); oMail = oMail->Decrypt(NULL); } if(oMail->IsSigned == VARIANT_TRUE) { ICertificatePtr oCert = oMail->VerifySignature(); MessageBox(NULL, _T("This email contains a valid digital signature."), NULL, MB_OK); //you can add the certificate to your certificate storage like this //oCert->AddToStore(CERT_SYSTEM_STORE_CURRENT_USER, _T("addressbook")); // then you can use send the encrypted email back to this sender. } } catch(_com_error &ep) { MessageBox(NULL, (TCHAR*)ep.Description(), NULL, MB_OK); } ::CoUninitialize(); }
[Delphi] const CRYPT_MACHINE_KEYSET = 32; CRYPT_USER_KEYSET = 4096; CERT_SYSTEM_STORE_CURRENT_USER = 65536; CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072; procedure VerifyAndDecryptEmail(); Var oMail: TMail; oCert: TCertificate; oSignerCert: ICertificate; begin oMail := TMail.Create(Application); oMail.LicenseCode := 'TryIt'; oMail.LoadFile('d:\test.eml', false); if oMail.IsEncrypted then try // this email is encrypted, decrypt it by default user certificate oMail.ConnectTo(oMail.Decrypt(nil)); // You can also use specified certificate like this // oCert := TCertificate.Create(Application); // oCert.LoadFromFile('c:\test.pfx', 'pfxpassword', CRYPT_USER_KEYSET); // oMail.Load(oMail.Decrypt(oCert.DefaultInterface).Content); except on ep: exception do ShowMessage('Decrypt Error: ' + ep.Message); end; if oMail.IsSigned then try // this email is digital signed, verify signature oSignerCert := oMail.VerifySignature(); ShowMessage('This email contains a valid digital signature.'); // You can add the certificate to your certificate storage like this // oSignerCert.AddToStore(CERT_SYSTEM_STORE_CURRENT_USER, // 'addressbook'); // Then you can use send the encrypted email back to this sender. except on ep: Exception do ShowMessage('Verify signature Error: ' + ep.Message); end; end;

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 & Web Application

Since ASP application is running under IUSER_MACHINE 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, CRYPT_MACHINE_KEYSET should be used instead of CRYPT_USER_KEYSET.

Example

[Visual Basic 6.0]
Const CERT_SYSTEM_STORE_CURRENT_USER = 65536
Const CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072

If (oMail.IsEncrypted) Then
        Dim oCert As New EAGetMailObj.Certificate
        oCert.LoadFromFile "c:\test.pfx", "pfxpassword", CRYPT_MACHINE_KEYSET 
        Set oMail = oMail.Decrypt(oCert)
End If

[VBScript]
Const CERT_SYSTEM_STORE_CURRENT_USER = 65536
Const CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072

If (oMail.IsEncrypted) Then
        Dim oCert 
        Set oCert = CreateObject("EAGetMailObj.Certificate")
        oCert.LoadFromFile "c:\test.pfx", "pfxpassword", CRYPT_MACHINE_KEYSET 
        Set oMail = oMail.Decrypt(oCert)
End If

[Visual C++]
if(oMail->IsEncrypted == VARIANT_TRUE)
{
    ICertificatePtr oCert;
    oCert.CreateInstance(__uuidof(EAGetMailObjLib::Certificate));
    oCert->LoadFromFile(_T("c:\\test.pfx"), _T("pfxpassword"),  CRYPT_MACHINE_KEYSET);
    oMail = oMail->Decrypt(oCert);   
}

See Also

Using EAGetMail POP3 & IMAP4 ActiveX Object
Digital Signature and E-mail Encryption/Decryption
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 ActiveX Object References
EAGetMail POP3 & IMAP4 Component Samples

Online Tutorials

Verify Digital Signature and Decrypt Email in VB6 - Tutorial
Verify Digital Signature and Decrypt Email in Delphi - Tutorial
Verify Digital Signature and Decrypt Email in VC++ - Tutorial