Rebex Mail Pack
IMAP, POP3, SMTP, EWS, MSG, MS Graph, MIME, S/MIME libraries for .NET
Download 30-day free trial Buy from $299More .NET libraries
-
Rebex File Transfer Pack
FTP and SFTP together
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
S/MIME - secure mail
On this page:
The sample code in this section uses our certificates and certificate store API.
If you are new to X.509 certificates and public key cryptography, check out our introduction.
Signature algorithms
Rebex S/MIME library supports following signature algorithms:
- RSA with SHA-256
- RSA with SHA-384
- RSA with SHA-512
- RSA with SHA-1*
- RSA with MD5*
- RSA with MD4*
- DSA with SHA-1*
And the following signature padding schemes:
- Public-Key Cryptography Standards (PKCS) #1 v1.5
- Probabilistic Signature Scheme (PSS)
* MD5 and MD4 are no longer considered secure. They are only intended for interoperability with legacy systems.
Signing mail messages
To sign an e-mail message, you need a suitable signer certificate and a corresponding private key. Please note that the private key is only needed for signing, not for validating the signature.
The following code shows how to sign a mail message using a certificate with private key loaded from a .PFX/.P12 file:
// create mail var mail = new Rebex.Mail.MailMessage(); // fill some fields // ... // prepare certificate for signing // - Certificate with private key is necessary for signing Certificate signer = Certificate.LoadPfx(@"C:\MyData\certificate.pfx", "password"); // sign the mail mail.Sign(signer);
' create mail Dim mail = New Rebex.Mail.MailMessage() ' fill some fields ' ... ' prepare certificate for signing ' - Certificate with private key is necessary for signing Dim signer As Certificate = Certificate.LoadPfx("C:\MyData\certificate.pfx", "password") ' sign the mail mail.Sign(signer)
Signing using RSA with PSS (RSASSA-PSS)
To sign an e-mail message using RSASSA-PSS padding scheme (as defined by RFC 8017),
use MailSignatureParameters
and specify MailSignaturePaddingScheme.Pss
for padding scheme:
// create mail var mail = new Rebex.Mail.MailMessage(); // fill some fields // ... // prepare certificate for signing // - Certificate with private key is necessary for signing Certificate signer = Certificate.LoadPfx(@"C:\MyData\certificate.pfx", "password"); // define signing parameters var parameters = new MailSignatureParameters() { PaddingScheme = MailSignaturePaddingScheme.Pss, HashAlgorithm = MailHashingAlgorithm.SHA256, }; // sign the mail mail.Sign(parameters, signer);
' create mail Dim mail = New Rebex.Mail.MailMessage() ' fill some fields ' ... ' prepare certificate for signing ' - Certificate with private key is necessary for signing Dim signer As Certificate = Certificate.LoadPfx("C:\MyData\certificate.pfx", "password") ' define signing parameters Dim parameters As New MailSignatureParameters() With parameters .PaddingScheme = MailSignaturePaddingScheme.Pss .HashAlgorithm = MailHashingAlgorithm.SHA256 End With ' sign the mail mail.Sign(parameters, signer)
Validating signature
To validate a mail message signature, you only need access to the signer's certificate. No private key is needed.
Signer certificate is usually embedded inside the S/MIME message itself.
If it's not, MailMessage
tries locating it in the current user's certificate store).
In both cases, you only have to call the ValidateSignature
method:
// load a mail var mail = new Rebex.Mail.MailMessage(); mail.Load(@"C:\MyData\mail.eml"); // validate the signature if the message is signed if (mail.IsSigned) { MailSignatureValidity result = mail.ValidateSignature(); if (result.Valid) Console.WriteLine("The message is signed and the signature is valid."); else Console.WriteLine("Signature of the message is not valid ({0}).", result.Status); } else { Console.WriteLine("The message is not signed."); }
' load a mail Dim mail = New Rebex.Mail.MailMessage() mail.Load("C:\MyData\mail.eml") ' validate the signature if the message is signed If mail.IsSigned Then Dim result As MailSignatureValidity = mail.ValidateSignature() If result.Valid Then Console.WriteLine("The message is signed and the signature is valid.") Else Console.WriteLine("Signature of the message is not valid ({0}).", result.Status) End If Else Console.WriteLine("The message is not signed.") End If
Encryption algorithms
Rebex S/MIME library supports following encryption algorithms:
- AES-128, AES-192, AES-256
- 3DES
- DES (intended for interoperability with legacy systems)
- RC2 (intended for interoperability with legacy systems)
and following encryption padding schemes:
- Public-Key Cryptography Standards (PKCS) #1 v1.5
- Optimal Asymmetric Encryption Padding (OAEP)
Encrypting mail messages
Encrypting a message with a certificate produces a message that can only be decrypted by the owner of the certificate's private key. It is possible to use multiple certificates for encryption - any one of them can decrypt the message.
Please note that only the message body is encrypted - everyone can still read the message headers such as From, To, Date or Subject.
Usually, the sender encrypts the message using his certificate in addition to the recipients certificate. This makes it possible for both the sender and the recipient (but no one else) do decrypt the message later.
The Following code shows how to encrypt a mail message using a recipient and sender certificates:
// create mail var mail = new Rebex.Mail.MailMessage(); // fill some fields // ... // load receiver's certificate // - For encryption, receiver's public key is necessary Certificate recipient = Certificate.LoadDer(@"C:\MyData\ReceiverCertificate.der"); // load sender's (my) certificate // - For encryption, only the public key is necessary, // however, loading certificate with private key e.g. PFX is also possible Certificate sender = Certificate.LoadDer(@"C:\MyData\MyCertificate.der"); // encrypt the message using both receiver's and sender's certificates // - It allows the sender to decrypt the message later // - If the message is encrypted using the receiver's certificate only, // only the recipient will be able to decrypt the message mail.Encrypt(recipient, sender);
' create mail Dim mail = New Rebex.Mail.MailMessage() ' fill some fields ' ... ' load receiver's certificate ' - For encryption, receiver's public key is necessary Dim recipient As Certificate = Certificate.LoadDer("C:\MyData\ReceiverCertificate.der") ' load sender's (my) certificate ' - For encryption, only the public key is necessary, ' however, loading certificate with private key e.g. PFX is also possible Dim sender As Certificate = Certificate.LoadDer("C:\MyData\MyCertificate.der") ' encrypt the message using both receiver's and sender's certificates ' - It allows the sender to decrypt the message later ' - If the message is encrypted using the receiver's certificate only, ' only the recipient will be able to decrypt the message mail.Encrypt(recipient, sender)
Encrypting using RSA with OAEP (RSAES-OAEP)
To encrypt an e-mail message using RSAES-OAEP padding scheme (as defined by RFC 8017),
use MailEncryptionParameters
and specify MailEncryptionPaddingScheme.Oaep
for padding scheme:
// create mail var mail = new Rebex.Mail.MailMessage(); // fill some fields // ... // load receiver's certificate // - For encryption, receiver's public key is necessary Certificate recipient = Certificate.LoadDer(@"C:\MyData\ReceiverCertificate.der"); // load sender's (my) certificate // - For encryption, only the public key is necessary, // however, loading certificate with private key e.g. PFX is also possible Certificate sender = Certificate.LoadDer(@"C:\MyData\MyCertificate.der"); // define encryption parameters var parameters = new MailEncryptionParameters() { EncryptionAlgorithm = MailEncryptionAlgorithm.AES256, PaddingScheme = MailEncryptionPaddingScheme.Oaep, HashAlgorithm = MailHashingAlgorithm.SHA256, }; // encrypt the message using both receiver's and sender's certificates // - It allows the sender to decrypt the message later // - If the message is encrypted using the receiver's certificate only, // only the recipient will be able to decrypt the message mail.Encrypt(parameters, recipient, sender);
' create mail Dim mail = New Rebex.Mail.MailMessage() ' fill some fields ' ... ' load receiver's certificate ' - For encryption, receiver's public key is necessary Dim recipient As Certificate = Certificate.LoadDer("C:\MyData\ReceiverCertificate.der") ' load sender's (my) certificate ' - For encryption, only the public key is necessary, ' however, loading certificate with private key e.g. PFX is also possible Dim sender As Certificate = Certificate.LoadDer("C:\MyData\MyCertificate.der") ' define encryption parameters Dim parameters As New MailEncryptionParameters() With parameters .EncryptionAlgorithm = MailEncryptionAlgorithm.AES256 .PaddingScheme = MailEncryptionPaddingScheme.Oaep .HashAlgorithm = MailHashingAlgorithm.SHA256 End With ' encrypt the message using both receiver's and sender's certificates ' - It allows the sender to decrypt the message later ' - If the message is encrypted using the receiver's certificate only, ' only the recipient will be able to decrypt the message mail.Encrypt(parameters, recipient, sender)
Use MailEncryptionParameters.Label
to specify OAEP label (also known as input parameter).
Use MailEncryptionParameters.Label
to specify OAEP label (also known as input parameter).
Decrypting mail messages
To decrypt a mail message, you must have access to the private key corresponding to one of the certificates used for message encryption.
By default, MailMessage
tries locating a suitable private key in the current user's key store.
The following code shows how to decrypt a mail message:
// load a mail var mail = new Rebex.Mail.MailMessage(); mail.Load(@"C:\MyData\mail.eml"); // decrypt the message if it is encrypted if (mail.IsEncrypted) { if (mail.CanDecrypt) { mail.Decrypt(); Console.WriteLine("The message was decrypted successfully."); } else { Console.WriteLine("You don't have the private key to decrypt the message."); } } else { Console.WriteLine("The message is not encrypted."); }
' load a mail Dim mail = New Rebex.Mail.MailMessage() mail.Load("C:\MyData\mail.eml") ' decrypt the message if it is encrypted If mail.IsEncrypted Then If mail.CanDecrypt Then mail.Decrypt() Console.WriteLine("The message was decrypted successfully.") Else Console.WriteLine("You don't have the private key to decrypt the message.") End If Else Console.WriteLine("The message is not encrypted.") End If
Combining encryption and signature
A mail message can be both signed and encrypted. This ensures message integrity, confidentiality, and authentition of the sender.
There are two ways to produce a message that is both encrypted and sign:
- Encrypt a signed message (sign first, then encrypt).
- Sign an encrypted message (encrypt first, then sign).
In the first case, no one but the recipient will be able to validate the signature and access the message content. In the second case, no one but the recipient will be able to access the message content, but anyone will be able to validate the signature.
Both ways have their pros and cons, but there is a very strong reason to prefer the first way: Some e-mail clients (such as Outlook Express or Windows Live Mail) do not handle the second way correctly, and claim the correct signature is not valid.
The following code signs a message and encrypts it:
// create mail var mail = new Rebex.Mail.MailMessage(); // fill some fields // ... // load sender's certificate Certificate signer = Certificate.LoadPfx(@"C:\MyData\MyCertificate.pfx", "password"); // load receiver's certificate Certificate recipient = Certificate.LoadDer(@"C:\MyData\ReceiverCertificate.der"); // sign the message using sender's certificate mail.Sign(signer); // encrypt the message using both receiver's and sender's certificates mail.Encrypt(recipient, signer);
' create mail Dim mail = New Rebex.Mail.MailMessage() ' fill some fields ' ... ' load sender's certificate Dim signer As Certificate = Certificate.LoadPfx("C:\MyData\MyCertificate.pfx", "password") ' load receiver's certificate Dim recipient As Certificate = Certificate.LoadDer("C:\MyData\ReceiverCertificate.der") ' sign the message using sender's certificate mail.Sign(signer) ' encrypt the message using both receiver's and sender's certificates mail.Encrypt(recipient, signer)
Back to feature list...