EWS: How to send signed email using the EWS Managed API

A question that keeps popping up is how to send signed or encrypted email using EWS.  A colleague (thank-you Vladimir!) has recently put together some sample code showing how to do exactly that using the EWS Managed API.  Based on his sample code, I've been able to partially complete my Windows Forms application that shows how this can be done.  The basic idea is to create the Mime content, then sign that content and write it to the MimeContent property.  Vladimir's code (below) shows how to do this from scratch building your own message.  My adaptation, in the attached Visual Studio 2015 solution, creates an EWS message as normal, then uses EWS to create the actual Mime (by saving the message as a draft then reading it back) - this is then read, signed, and written back to the message.  The advantage of this is that you can easily add attachments and anything else needed without having to learn how this works at an email level (i.e. you can just let EWS do this for you).

So, to the code:

var cert = new X509Certificate2(@"..\..\..\UserA_cert_for_email.pfx", "1234");

var mail = new EmailMessage(exchService);
mail.ItemClass = "IPM.Note.SMIME";
var msgId = Guid.NewGuid().ToString("N");
var boundary = "----=_NextPart_" + msgId + "." + (new Random(100)).Next(999999);
var sb = new StringBuilder();
sb.AppendLine("From: UserA@vd-test.local");
sb.AppendLine("To: UserA@vd-test.local");
sb.AppendLine("Subject: SMIME test subject " + (new Random(100)).Next(999));
sb.AppendLine("Message-ID:\n <" + msgId + "@vd-srv08r2-dc.vd-test.local>");
sb.AppendLine("Content-Language: en-US");
sb.AppendLine("Content-Type: application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"");
sb.AppendLine("Content-Disposition: attachment; filename=\"smime.p7m\"");
sb.AppendLine("Content-Transfer-Encoding: base64");
sb.AppendLine("MIME-Version: 1.0");

var mimeHeader = sb.ToString();


sb.AppendLine("Content-Type: multipart/alternative;");
sb.AppendLine("\tboundary=\"" + boundary + "\"");
sb.AppendLine("This is a multipart message in MIME format.");
sb.AppendLine("--" + boundary);
sb.AppendLine("Content-Type: text/plain;");
sb.AppendLine("Content-Transfer-Encoding: 7bit");
sb.AppendLine("I am manually generated signed message.");
sb.AppendLine("--" + boundary);
sb.AppendLine("Content-Type: text/html;");
sb.AppendLine("Content-Transfer-Encoding: quoted-printable");
sb.AppendLine("<html><head/><body><p>Hello!</p><p>I am manually generated signed message.</p></body></html>");
sb.AppendLine("--" + boundary);

var bodyBytes = Encoding.ASCII.GetBytes(sb.ToString());
var content = new ContentInfo(bodyBytes);
SignedCms signedCms = new SignedCms(content, false);
CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert);
var bodySignedBytes = signedCms.Encode();

mimeHeader += Convert.ToBase64String(bodySignedBytes);
mail.MimeContent = new MimeContent(Encoding.ASCII.HeaderName, Encoding.ASCII.GetBytes(mimeHeader));

The sample application can be downloaded below.  Note that while the application states it can encrypt and sign email, I haven't yet completed the encryption part.  When I get a chance I'll add that and update.  The application looks like this:


Comments (3)

  1. AlexS says:

    What about OpenPGP signed messages? How does this work?

  2. act005 says:

    How to enable sign , encryption both.i aupdated code as following and it shows encryption icon but not both sign and encryption icons in outlook

    // The remaining Mime is what we need to sign/encrypt

    mimeContent = Encoding.ASCII.GetBytes(sMIMEForEncryption.ToString());
    byte[] signedMime = Sign(mimeContent, signingCertificate);

    // Build the complete Mime again (headers + signed Mime)

    //Encrypt signedMime
    EnvelopedCms Envelope = new EnvelopedCms(new ContentInfo(signedMime));
    CmsRecipient Recipient = new CmsRecipient(
    SubjectIdentifierType.IssuerAndSerialNumber, signingCertificateEncrypt);
    byte[] EncryptedBytes = Envelope.Encode();

    string sMime = sHeaders.ToString();
    sMime += Convert.ToBase64String(EncryptedBytes);

    message.ItemClass = “IPM.Note.SMIME”;
    message.MimeContent = new MimeContent(Encoding.ASCII.HeaderName, Encoding.ASCII.GetBytes(sMime));


    1. RafaelV10 says:

      Hello, i’m new with this.
      I’m trying to add an attachment for sending a signed mail so i try :

      sb.AppendLine(“Content-Disposition: attachment; filename=\”path_to_my_file\””);

      and i receive the mail, but not my file as attachment.

      My file exists well in the path

      Someone to help me ?

Skip to main content