SingingEels : Development Community & Resource

Login

Articles

  • ADO.NET (2)
  • ASP.NET (31)
  • LINQ (4)
  • Security (2)
  • Silverlight (2)
  • SQL (7)
  • Standards (5)
  • WCF (1)

Syndication

  • Articles RSS
  • Blogs RSS

Contribute

  • Our Authors List
  • Member Sign-Up
  • Suggestions Box

Sending Encrypted Emails With S/MIME Protocol

(May 21 2007 - 02:10:15 PM by Jonathan DeMarks) - [print article]

Executive Overview

If you've ever needed to send an encrypted email you know the pain of dealing with third party encryption and decryption tools especially if you need to try to explain and support them for people in management. The S/MIME protocol takes care of all the dirty work for you, allowing seemingly transparent encryption and decryption that works beautifully with all the major email applications available today.

The Pain of S/MIME

The problem encountered by programmers is how to programmatically send S/MIME encrypted emails from an automated process without going bald from the almost endless complexity introduced by this method. Today I will present an overview of how an S/MIME email is sent and what is involved in the process as well as hand out some sample code in the form of a C# console application.

How S/MIME Emails Work (Basically…)

In as short terms as possible, a normal email message is just plain text. S/MIME extends this by wrapping that text in binary. It is possible to think of it as stuffing envelopes inside of envelopes (to use a mail analogy.) The email message is the letter, which can then be signed (another envelope) and then encrypted (yet another, possibly metal envelope.)

Show Me the Code

So here’s a simple C# example of just that (I use C# because it is simple to understand and free to use.) It takes a signing certificate, and encrypting certificate, to, from, a subject, a body, the server, its port, and if the email is in HTML or not. The encoding must be in 7bit, but that’s ok because it must be at least that to use attachments (which are not demonstrated but could easily be done.)

using System;
using System.IO;
using System.Text;
using System.Net.Mail;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;

namespace EncryptedSMIME
{
   class Program
   {
       static void Main(string[] args)
       {
           SendEncryptedEmail("Cert.pfx", "thawte.cer",
               "\"Noah Body\" <nbody@email.com>",
               "\"John Doe\" <jdoe@email.com>",
               "Test C# Encrypted HTML EMail",
               "This email is encrypted and signed.",
               "smtp.singingeels.com", 25, false);
       }

       static void SendEncryptedEmail(
           string SigningCertPath, string EncryptingCertPath,
           string To, string From, string Subject, string Body,
           string SmtpServer, int SmtpPort, bool HTML)
       {
           X509Certificate2 SignCert = new X509Certificate2(SigningCertPath, "password");
           X509Certificate2 EncryptCert = new X509Certificate2(EncryptingCertPath, "");

           StringBuilder Message = new StringBuilder();
           Message.AppendLine("Content-Type: text/" + ((HTML) ? "html" : "plain") +
               "; charset=\"iso-8859-1\"");
           Message.AppendLine("Content-Transfer-Encoding: 7bit");
           Message.AppendLine();
           Message.AppendLine(Body);

           byte[] BodyBytes = Encoding.ASCII.GetBytes(Message.ToString());

           EnvelopedCms ECms = new EnvelopedCms(new ContentInfo(BodyBytes));
           CmsRecipient Recipient = new CmsRecipient(
               SubjectIdentifierType.IssuerAndSerialNumber, EncryptCert);
           ECms.Encrypt(Recipient);
           byte[] EncryptedBytes = ECms.Encode();

           SignedCms Cms = new SignedCms(new ContentInfo(EncryptedBytes));
           CmsSigner Signer = new CmsSigner
               (SubjectIdentifierType.IssuerAndSerialNumber, SignCert);

           Cms.ComputeSignature(Signer);
           byte[] SignedBytes = Cms.Encode();

           MailMessage Msg = new MailMessage();
           Msg.To.Add(new MailAddress(To));
           Msg.From = new MailAddress(From);
           Msg.Subject = Subject;

           MemoryStream ms = new MemoryStream(EncryptedBytes);
           AlternateView av = new AlternateView(ms,
               "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
           Msg.AlternateViews.Add(av);

           SmtpClient smtp = new SmtpClient(SmtpServer, SmtpPort);
           smtp.UseDefaultCredentials = true;
           smtp.Send(Msg);
       }
   }
}

About the Encryption

The encryption used is an asymmetric certificate type. This means that the sender has the public key and the recipient has the private key. If you find yourself sending to a list of people, try to find another way as giving multiple people a private key is not necessarily a good idea from a security perspective, however if the email is only going to one person or to an automated process which further controls security, it is a simple way to get the job done.

Final Words

This is not a simple code example, but it does work. You may take the sample and use it directly or modify for your own uses. Please note the security concerns addressed in the above paragraph and happy coding to you!

  • Jul 24 2007 - 09:49:57 PM frubim1

    Hi Jonathan!

    Do you happen to have a code example where we can send an encrypted email (the body), as your article, but sending an encrypted attachment as well?

    Thanks,

    Felipe

  • Aug 06 2007 - 09:18:30 AM Jonathan DeMarks

    Felipe,

    My apologies, however the current System.Net.Mail classes will not support this functionality. If I were to compose the entire mail message and manually send it to the SMTP server, it would be possible. For now it's better to use a CDONTS wrapper or a class that is specifically designed for this functionality.

    Thanks!

    Jon

  • Oct 08 2007 - 07:36:20 PM EnoshChang

    Hi Jonathan:

    If I want to send a signed and encrypted mail, how can I do? Thanks!

    Enosh

  • Jan 16 2008 - 04:54:12 AM PiMichalak

    Hi, It's great post. Can you give me solution for sending signed and encrypted email via .net 2.0 like this one, but this solution not working.

    Thx, Peter

You must be logged in to add comments. If you have not already done so, you can create an account here. If you already are a member, you first need to login before you can comment.

People to Follow

Experts in the categories related to this article.

There are no experts related to this article.

Related Blogs

These are the most recent blog posts related to this article.

There are no blog posts related to this article.

Related Ads

SingingEels.com as of Aug 20 2008 - 08:56:02 PM - (0.1875)