About: Encrypting or signing a message programmatically

We get cases on encrypting email from time to time.   With Microsoft messaging APIs, sending an encrypted or signed message is not just  matter of flipping flag or pointing to a certificate.  The easiest is going to be using Outlook Object Model (OOM);  however, because of its user tied usage it cannot be used in a web page, service or any application where there is not a logged on user watching over the application.  API such as System.Net.Mail (SNM) and the older System.Web.Mail never had support for signed messages nor did they expose access to the underlying MIME stream, whish would be needed to encrypt the message contents.  With SNM you may be able to encrypt just the body alone, however this seems to have some issues when there are attachments.  There is no support for writing code to send an encrypted or signed message with SNM or SWM.  You could use CDOSYS to create a message and sign and possibly encrypt its  - however, since CDOSYS does not support such encryption/signing natively and that doing such operations is going to mean your going to be changing the MIME programmatically without an API designed to do so and that means its not really supported.  With EWS you would need to create an entire MIME message with encrypted/signed content.  While EWS supports creating items with MIME there is no developer support for creating custom MIME content other than with what is generated via Microsoft APIs.

What's needed to encrypt an entire message prior to sending it?

  • A certificate
  • One of the following:
    • An API which can inherently encrypt the message with an installed certificate.
    • An API which provides access to the full MIME of the message. The certificate will need to be obtainable and the password supplied. An encryption API will need to be used in conjunction with the messaging API.

System.Net.Mail (SNM):

APIs such as System.Net.Mail (SNM) and System.Web.Mail (SWM) do not provide access to the underlying MIME stream of the message, so they are not good candidates for encrypting or signing a message.

In theory if an email is sent to a pick-up folder a secondary application could be used to read and parse the message then encrypt the entire message and also resubmit it. The problem with that approach is it may not be highly scalable.

Another option if there are no attachments for the message is to try to encrypt just the body of the message.  Note that this won't help when there are attachments since they are not part of the body being encrypted and this approach may not work at all even for the body of the message.

Sending encrypted e-mail with C#
hthttps://www.diaryofaninja.com/blog/2009/10/02/sending-encrypted-email-with-c
Note that this is a third party site and is not endorsed or recommended by Microsoft.

CDOSYS:

CDOSYS can access the MIME of the message and be used for signing and encryption.  Since it allows you to also get the full MIME of a message, you can use its MIME generation abilities to create MIME to be used in creating a signed/encrypted message for usage with EWS.   Note that you will need to have a certificate already installed in Outlook for this to work.  While CDOSYS is a very old API, it you should understand its still fully supported and that it does things which no other API can do. Also, its fully supported under .NET and in a service.

How to send digitally signed messages by using CDOSYS/CDOEX
https://support.microsoft.com/en-us/kb/280391

How To  Create a Multipart SMIME Signature by Using CAPICOM and CDO
https://support.microsoft.com/en-us/kb/318215

As with any .NET code which uses COM objects, you should be careful to properly release memory on the underlying CDOSYS COM objects (i.e. call Marshal.ReleaseCOMObject):

https://blogs.msdn.com/b/mstehle/archive/2007/12/06/oom-net-part-1-introduction-why-events-stop-firing.aspx

https://blogs.msdn.com/b/mstehle/archive/2007/12/07/oom-net-part-2-outlook-item-leaks.aspx

https://blogs.msdn.com/b/mstehle/archive/2008/02/18/oom-net-part-3-back-to-the-basics-msdn-must-reads.aspx

https://blogs.msdn.com/b/mstehle/archive/2008/06/12/oom-net-part-5-event-planning.aspx

https://blogs.msdn.com/b/webdav_101/archive/2015/08/04/why-does-appointmentitem-userproperties-find-leak-under-net.aspx

Exchange Web Services (EWS):

EWS has no native ability to create signed or encrypted messages.  You will need to create a message as encrypted MIME.  There is no developer support for creating MIME without the usage of a Microsoft API which is designed to do so.  So, one way to get past this limitation is to create a signed message using CDOSYS and extract the final MIME then use EWS to create the message with that MIME.

You can also just sign the message body:

EWS: How to send signed email using the EWS Managed API
https://blogs.msdn.com/b/emeamsgdev/archive/2015/08/10/ews-how-to-send-signed-email.aspx

Outlook Object Model (OOM):

How to sign or encrypt a message programmatically from OOM
https://blogs.msdn.com/b/dvespa/archive/2009/03/16/how-to-sign-or-encrypt-a-message-programmatically-from-oom.aspx

Information on signing and encryption:

2.1.3.2 Opaque-Signed and Encrypted S/MIME Message
https://msdn.microsoft.com/en-us/library/ee159350(v=exchg.80).aspx

[MS-OXOSMIME]: S/MIME Email Object Algorithm
https://msdn.microsoft.com/en-us/library/cc433474(v=exchg.80).aspx