Home > C# > Encrypting and signing Mail in .Net part 3/5 (Building the content – with attachments)

Encrypting and signing Mail in .Net part 3/5 (Building the content – with attachments)

Lets get startet with the real stuff on how to encrypt mail with c#

Now we have created the certificats and we have the methods for retrieving them. So before we can sign and encrypt the mail we need to prepare there content for security operations. When sending encrypted mail with attachment the content should be included as a part of the content. If add an attahcment to an email with  using the normal “System.net.mail – message.attachments.add() ” breaks the encryption. To overcome this the attachments are added to the maincontent of message but seprated with boundries.

Link to part 1, part 2

Since there are different ways to fetch filecontent and bodycontent i’ve have focused only on howto message data should be build, so there are left some work for you to do. Implementing functions for retrieving filecontent into byte[] fx.

To make the next couple of step easier to connecto to this one which is the backbone in encrypting the mail, I will make a simple builcontent() function that builds a simple text/plain mail and adds an attachment called snebar.jpg placed on the root of my c drive.

public string buildMessageContent()
{
string messageBoundry = "--PTBoundry=2";
StringBuilder message = new StringBuilder();
message.Append("\r\n");
message.Append("\r\n");
message.Append("--");
message.Append(messageBoundry + "\r\n");
message.Append("Content-Type: text/plain; charset=us-ascii\r\n");
//could use text/html as well here if you want a html message
message.Append("Content-Transfer-Encoding: ");
message.Append(TransferEncoding.QuotedPrintable);
message.Append("\r\n\r\n");
message.Append("TEST AF kryptering")//BODY TEXT GOES HERE

message.Append("\r\n");

//ADD file section
//could be filename or whatever
//foreach (string filename in attachments){
//Read file part implement your own
byte[] buff = null;
FileStream fs = new
FileStream("c:\\snebaer.jpg", FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo("c:\\snebaer.jpg").Length;
buff = br.ReadBytes((int)numBytes);
byte[] bytes = buff;
//Setup filecontent
String filecontent =
Convert.ToBase64String(bytes,Base64FormattingOptions.InsertLineBreaks);

message.Append("--");
message.Append(messageBoundry);
message.Append("\r\n");
message.Append("Content-Type: ");
message.Append("application/octet-stream;");
message.Append("name=c:\\snebaer.jpg");
message.Append("\r\n");
message.Append("Content-Transfer-Encoding: base64\r\n\r\n");
message.Append(filecontent);
message.Append("\r\n\r\n");
//} //END FILSECTION

message.Append("--");
message.Append(messageBoundry);
message.Append("--\r\n");
return message.ToString();
}<br>

Note that there isout comment foreach loop which could added if you need to add multiple attachments. I will also be a good idee to ad at method for building unique boundaries that could be used you can use Guid or what ever you like. I use theese static one so it easier to refence them in the next post. the string returned here is now readyto be signed. Look

Categories: C# Tags: ,
  1. kerry
    28/01/2015 at 21:45

    Thanks! Your code worked perfectly.

    Here is my version of your design in VB.NET:

    Friend Function sendInternalEncrypt(sRecipType As String, sAddr As String, sSubject As String, sText As String, attachmentList As List(Of String)) As Boolean
    Dim EmailSender As String = “DoNotReply@va.gov”
    Dim EmailRecipient As String = sAddr
    Dim EmailSubject As String = sSubject
    Dim EmailText As String = sText
    Dim sAttachmentText As String = “”
    Dim sAttachmentRichtext As String = “”
    Dim sAtt As String = “”
    Dim sAttachmentTextContent As String = “”
    Dim sAttachmentRichtextContent As String = “”
    Dim sAttachmentTextName As String = “”

    Try
    ‘ldap servers
    Dim ldapServerVBA As String = “LDAP://someServer.va.gov:389”
    Dim ldapServerNCA As String = “LDAP://someServer:389”
    Dim ldapServerVA As String = “LDAP://someServer.va.gov:389”

    ‘get certificate of recipient from 1 of 3 ldap servers
    Dim cert As X509Certificate2
    Dim zeroPtr As IntPtr = CType(0, IntPtr)
    cert = GetRecipientCertificate(EmailRecipient, ldapServerVBA)
    If cert.Handle = zeroPtr Then
    cert = GetRecipientCertificate(EmailRecipient, ldapServerNCA)
    If cert.Handle = zeroPtr Then
    cert = GetRecipientCertificate(EmailRecipient, ldapServerVA)
    End If
    End If

    If cert.Handle = zeroPtr Then
    Throw New ArgumentException(EmailRecipient & “: Certificate not found.”)
    Else
    ‘construct an instance of the CmsRecipient class
    ‘by using the specified recipient certificate.
    Dim cmsRecipient As CmsRecipient = New CmsRecipient(cert)

    ‘build big string
    Dim s As StringBuilder = New StringBuilder
    s.AppendLine(“content-type: multipart/mixed; boundary=makeANewPart”)
    s.AppendLine()
    s.AppendLine(“–makeANewPart”) ‘— part1 contains the plain text body
    s.AppendLine(“content-type: text/plain; charset=us-ascii”)
    s.AppendLine(“Content-Transfer-Encoding: Quoted-Printable”)
    s.AppendLine()
    s.AppendLine(EmailText)
    s.AppendLine()

    ‘add attachments to big string
    For Each sAtt In attachmentList
    If sAtt.Length > 0 Then
    s.AppendLine(“–makeANewPart”) ‘ make a new part for each attachment
    Dim filename As String = Path.GetFileName(sAtt)
    If filename.IndexOf(“.txt”, StringComparison.InvariantCultureIgnoreCase) > -1 Then
    ‘it’s a text file
    s.AppendLine(“content-type: text/plain; charset=us-ascii; name=” & filename)
    s.AppendLine(“Content-Transfer-Encoding: Quoted-Printable”)
    Using sr As StreamReader = New StreamReader(sAtt, True)
    s.AppendLine()
    s.AppendLine(sr.ReadToEnd())
    s.AppendLine()
    End Using
    ElseIf filename.IndexOf(“.csv”, StringComparison.InvariantCultureIgnoreCase) > -1 Then
    ‘it’s a csv file
    s.AppendLine(“content-type: text/csv; charset=us-ascii; name=” & filename)
    s.AppendLine(“Content-Transfer-Encoding: Quoted-Printable”)
    Using sr As StreamReader = New StreamReader(sAtt, True)
    s.AppendLine()
    s.AppendLine(sr.ReadToEnd())
    s.AppendLine()
    End Using
    ElseIf filename.IndexOf(“.rtf”, StringComparison.InvariantCultureIgnoreCase) > -1 Then
    ‘it’s rich text format.
    s.AppendLine(“content-type: application/rtf; name=” & filename)
    s.AppendLine(“Content-Transfer-Encoding: Quoted-Printable”)
    Using sr As StreamReader = New StreamReader(sAtt, True)
    s.AppendLine()
    s.AppendLine(sr.ReadToEnd())
    s.AppendLine()
    End Using
    ElseIf filename.IndexOf(“.pdf”, StringComparison.InvariantCultureIgnoreCase) > -1 Then
    ‘it’s a pdf file
    Dim buff() As Byte
    Dim fs As FileStream
    Dim br As BinaryReader
    fs = New FileStream(sAtt, FileMode.Open, FileAccess.Read)
    br = New BinaryReader(fs)
    Dim numbytes As Long = New FileInfo(sAtt).Length
    buff = br.ReadBytes(CInt(numbytes))
    Dim bytes() As Byte = buff
    Dim sPdfFileContent As String = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks)
    s.AppendLine(“content-type: application/pdf; name=” & filename)
    s.AppendLine(“Content-Transfer-Encoding: base64”)
    Using sr As StreamReader = New StreamReader(sAtt, True)
    s.AppendLine()
    s.Append(sPdfFileContent)
    s.AppendLine()
    End Using
    Else
    ‘I don’t encrypt this type of attachment
    writeToStatusFile(“sendInternalEncrypt()”, “Warning: I don’t encrypt this kind of attachment: ” & sAtt & ” So I’m skipping it.”)
    End If
    End If
    Next
    s.AppendLine()
    s.AppendLine(“–makeANewPart–“)
    s.AppendLine()

    ‘ convert big string to array of ASCII bytes
    Dim sBytes As Byte() = Encoding.ASCII.GetBytes(s.ToString())

    ‘ Build the e-mail body bytes into a secure envelope
    Dim ci As ContentInfo = New ContentInfo(sBytes)
    Dim envelopedCms As New EnvelopedCms(ci)

    ‘encrypt!
    envelopedCms.Encrypt(cmsRecipient)
    Dim EncryptedBytes As Byte() = envelopedCms.Encode()

    ‘Attach the encrypted body to the email as and ALTERNATE VIEW
    Dim sbldr As StringBuilder = New StringBuilder
    sbldr.Append(“application/pkcs7-mime;”)
    sbldr.Append(“smime-type=enveloped-data;”)
    sbldr.Append(“name=smime.p7m;”)
    sbldr.Append(“content-transfer-encoding=Base64;”)
    sbldr.Append(“content-disposition=attachment;”)
    sbldr.Append(“fileName=smime.p7m;”)
    Dim avString As String = sbldr.ToString
    Dim ms As New MemoryStream(EncryptedBytes)
    Dim av As New AlternateView(ms, avString)

    ‘get ready to send
    Dim oSmtpClient As SmtpClient = New SmtpClient(sSmtpServer, iSmtpPort)
    oSmtpClient.UseDefaultCredentials = True
    oSmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials

    ‘build mail message
    Dim mm As MailMessage = New MailMessage()
    Dim maFrom As MailAddress = New MailAddress(EmailSender)
    mm.From = maFrom
    mm.To.Add(EmailRecipient)
    mm.Subject = EmailSubject
    mm.AlternateViews.Add(av)

    ‘send email
    oSmtpClient.Send(mm)
    blnEmailSent = True

    ‘clean up
    ms.Dispose()
    oSmtpClient.Dispose()
    mm.Dispose()
    ms.Dispose()

    End If
    Catch ex As Exception
    blnEmailSent = False
    Dim sError As String = makeErrorString(“SendEmailInternalEncrypt”, ex)
    My.Computer.FileSystem.WriteAllText(sErrorFile, sError, True)
    End Try
    Return blnEmailSent

    End Function

  1. 15/05/2011 at 19:01
  2. 15/05/2011 at 19:33

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: