There are times when the invention that we all call E-mail just doesn’t cut it for sending information securely. It is because of this that in every case where information really needs to be sent securely E-mail is not usually the medium chosen to send it. As most developers know though there are times when you have to bite the unsecure E-mail bullet. I’ll show you a way to solve this conundrum and at the same time probably keep your current e-mail client.
Secure you say!? E-mail is not secure!
Not many people know who about the secure capabilities of e-mail, so it may come as a surprise that the method I'm going to show you in most cases will use the same e-mail client you are currently using and requires very little work to setup.
It is possible to encrypt your message’s contents and send this encrypted blob as an attachment known as an Alternate View. If the destination mail client has a copy of the encryption key it un-encrypts the attachment and displays it as the message itself.
Pretty neat huh?
Dot Net supports Personal (X509) Certificates out of the box – and this little baby packs a lot of punch when you want to get things done with secure e-mail. So we’re going to harness this power to make it happen with c#.
How to bake a cake
Today’s recipe is really very simple and requires only the following ingredients:
1. A personal SSL certificate
2. The code i provide below
Where do i get a personal SSL certificate from? Are they expensive?
Depending on your knowledge of SSL certificates you may be scratching your head as to what your next step may be. You may have never even heard of personal SSL certificates.
Luckily for you there is an ever need for simple personal SSL certificates. Furthermore, certain companies have decided that they will provide them for free to try and get you in the door on the more expensive certificates.
Most serious SSL providers can arrange one for you (you can even install your own certificate authority server if your so inclined). But for this exercise we are going to use the free personal email certificate service from Thwarte.
Thwarte offers free personal certificates at the following URL so simply go sign yourself up and grab one now – its that simple:
https://www.thawte.com/secure-email/personal-email-certificates/index.html
Installing the certificate
Now that you have your personal certificate, you want to go ahead and install it in your e-mail client. There are different instructions depending on your email client – I'm not going to go into much detail on how to do this as you probably have a different situation/OS/e-mail client than I do.
What i will do however is provide some information that shows you how to get it working on a few popular Windows clients:
If i haven’t listed your client and you want to find out how to “get it done” then maybe you need to make Google your friend. As mentioned that’s sadly not in the scope of this post.
Onwards and upwards.
Adding X509 Certificate support to your app
The next thing your going to have to do is add a reference to System.Security in your web app. This is not a common thing to use in a web app, but as this is where the Koolade is flowing from on our little adventure, you’ll have to go do this now.
Show me the code
So without further adieu…
The code below is an example of how to do what I've been babbling on about for the past few paragraphs – as i like to lead with examples I'll simply give you the code and you can take it from there :-)
I’ve added comments to the juicy bits to try and explain what we are doing as we go.
using System.IO; using System.Net.Mail; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Security.Cryptography.Pkcs; public class SendEncryptedEmail { public void SendEmail() { //set my certificate info up string CertificatePath = "C:\\my_sslcert.p12"; string CertificatePassword = "my certificate pass"; string MailServer = "mail.mydomain.com"; string EmailRecipient = "your@emailaddress.com"; string EmailSender = "your@sender.com"; string EmailSubject = "My first secure email"; string EmailBody = "This is a secure email"; bool IsHtmlEmail = false; //Load the certificate X509Certificate2 EncryptCert = new X509Certificate2(CertificatePath, CertificatePassword); //Build the body into a string StringBuilder Message = new StringBuilder(); Message.AppendLine("Content-Type: text/" + ((IsHtmlEmail) ? "html" : "plain") + "; charset=\"iso-8859-1\""); Message.AppendLine("Content-Transfer-Encoding: 7bit"); Message.AppendLine(EmailBody); //Convert the body to bytes byte[] BodyBytes = Encoding.ASCII.GetBytes(Message.ToString()); //Build the e-mail body bytes into a secure envelope EnvelopedCms Envelope = new EnvelopedCms(new ContentInfo(BodyBytes)); CmsRecipient Recipient = new CmsRecipient( SubjectIdentifierType.IssuerAndSerialNumber, EncryptCert); Envelope.Encrypt(Recipient); byte[] EncryptedBytes = Envelope.Encode(); //Creat the mail message MailMessage Msg = new MailMessage(); Msg.To.Add(new MailAddress(EmailRecipient)); Msg.From = new MailAddress(EmailSender); Msg.Subject = EmailSubject; //Attach the encrypted body to the email as and ALTERNATE VIEW 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(MailServer, 25); //send the email smtp.Send(Msg); } }
The results
Once you’ve got your certificate and pointed the above code at it you should be on your way to sending secure emails using c#.
Below is an example of a secure e-mail received using the above method in outlook 2007.
Inbox View
Message View