Sign and Unsign emails with S/MIME
The following example shows how you can use GemBox.Email to create an S/MIME email message by loading and signing a regular message.
using GemBox.Email;
using System.Security.Cryptography.X509Certificates;
class Program
{
static void Main()
{
// If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Load message from email file normally.
var message = MailMessage.Load("%InputFileName%");
// Signing an already signed message would throw an exception!
if (message.IsSigned)
return;
var options = new DigitalSignatureOptions()
{
Certificate = new X509Certificate2("%InputDigitalId%", "GemBoxPassword"),
ClearSigned = true
};
// Sign message as clear-signed.
message.Sign(options);
// Save the signed message.
message.Save("Signed.%OutputFileType%");
}
}
Imports GemBox.Email
Imports System.Security.Cryptography.X509Certificates
Module Program
Sub Main()
' If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Load message from email file normally.
Dim message = MailMessage.Load("%InputFileName%")
' Signing an already signed message would throw an exception!
If message.IsSigned Then Return
' Load certificate data.
Dim options As New DigitalSignatureOptions() With
{
.Certificate = New X509Certificate2("%InputDigitalId%", "GemBoxPassword"),
.ClearSigned = True
}
' Sign message as clear-signed.
message.Sign(options)
' Save the signed message.
message.Save("Signed.%OutputFileType%")
End Sub
End Module
You can convert a regular (unsigned) MailMessage
to an S/MIME message by calling MailMessage.Sign
, which will add a signature to the MailMessage
, and make it read-only. This method receives an instance of DigitalSignatureOptions
as a parameter, which contains:
- The certificate to be used while creating the signature through the
DigitalSignatureOptions.Certificate
property. - A boolean indicating if this should be a clear-signed (
true
) or an opaque-signed (false
) message through theDigitalSignatureOptions.ClearSigned
property.
Calling MailMessage.Sign
from a signed message will result in an InvalidOperationException
being thrown.
A signed MailMessage
has some differences compared to a regular MailMessage
that you should consider:
MailMessage.IsSigned
will be set totrue
, andMailMessage.MessageSecurity
will indicate the type of signature applied to this message.- Signed messages will be
read-only
. Changing the message's content (BodyText
,BodyTextCharset
,BodyHtml
orAttachments
) will result in anInvalidOperationException
being thrown. - It will be possible to validate the message's signature or to unsign it.
How to validate a signed email
The following example shows how to load a signed file and check its signature. You can use the input file selector to see how it works for valid or invalid signature files.
using GemBox.Email;
using System;
class Program
{
static void Main()
{
// If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Load message from email file normally.
MailMessage message = MailMessage.Load("%InputFileName%");
// Check if it's signed and validate signature.
Console.WriteLine($"Is signed: {message.IsSigned}");
Console.WriteLine($"Is valid: {message.ValidateSignature()}");
}
}
Imports GemBox.Email
Imports System
Module Program
Sub Main()
' If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Load message from email file normally.
Dim message = MailMessage.Load("%InputFileName%")
' Check if it's signed and validate signature.
Console.WriteLine($"Is signed: {message.IsSigned}")
Console.WriteLine($"Is valid: {message.ValidateSignature()}")
End Sub
End Module
GemBox.Email enables you to validate signed (S/MIME) messages. It supports both clear-signed (multipart/signed) and opaque-signed (application/pkcs7-mime) formats according to the latest S/MIME standard RFC 8551.
After loading or creating a signed message, it is possible to use MailMessage.ValidateSignature
to verify if the signature is valid. There are three conditions that are necessary for this method to return true
:
MailMessage.IsSigned
has to betrue
.- The certificate data embedded into the signature has to still be considered valid. Certificates are valid from a specific date to another specific date, so the date when the file is being signed has to be within this range.
- The message's content has to be precisely the same as the one used to generate the signature.
Each email engine or application has a different set of rules to consider a signature valid or not, so an email that is considered valid or invalid in some platform can have a different result with this method. For example: on Windows, Outlook will warn of a problem with signatures created by certificates not associated with a trusted authority.
Types of signatures
There are two types of signatures applied to two types of emails: clear-signed messages (with a signature that contains only data about the certificate and signature) and opaque-signed messages (with a signature that includes data about the certificate, signature, and source content used to generate the signature).
Clear-signed messages maintain the email's content separate from the signature, which means that even if an application (like Outlook or Gmail) does not know how to deal with signed messages, it will at least be able to show the original content normally.
Opaque-signed messages merge the email's content and signature in a binary format, meaning that an application (like Outlook or Gmail) can only show the content if it knows how to deal with opaque-signed messages.
You can further experiment with S/MIME message signing and validation using a simple trick:
- Access the example on how to sign messages to generate a clear-signed .eml file;
- Open the file in any text editor, locate the body's content, add or remove any character in it, and save the file;
- Open the file on Outlook and load it with GemBox.Email, both will consider it a valid signed email with an invalid signature.
GemBox.Email supports both clear-signed (multipart/signed) and opaque-signed (application/pkcs7-mime) formats as defined in the S/MIME standard (RFC 8551).
Unsign email messages in C# and VB.NET
The following example shows how to unsign an S/MIME message.
using GemBox.Email;
class Program
{
static void Main()
{
// If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Load message from email file normally.
var message = MailMessage.Load("%InputFileName%");
// To unsign a not-signed message would throw an exception!
if (!message.IsSigned)
return;
message.Unsign();
// Save the unsigned message.
message.Save("Unsigned.%OutputFileType%");
}
}
Imports GemBox.Email
Module Program
Sub Main()
' If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Load message from email file normally.
Dim message = MailMessage.Load("%InputFileName%")
' To unsign a Not-signed message would throw an exception!
If Not message.IsSigned Then Return
message.Unsign()
' Save the unsigned message.
message.Save("Unsigned.%OutputFileType%")
End Sub
End Module
To remove the signature or enable changing the content of a signed MailMessage
it is necessary to call MailMessage.Unsign
, which will remove the message's signature and its read-only estate, exposing the content as a "normal" message. If necessary, it is also possible to re-sign the message.
If you call MailMessage.Unsign
from an unsigned message, an InvalidOperationException
being thrown.