Home > C# > Encrypting and signing Mail in .Net part 4/5 (Signing the content)

Encrypting and signing Mail in .Net part 4/5 (Signing the content)

Okay so now we are done and have build the content of the mail. Now we need to sign it. If you dont want to sign the mail skip this part and jum straight to encrypting “which will be the next post”. I’ve found quite a few post on tje net on howto sign at encrypt mails but none of them worked for me. I’ve had to look at package and mail content to analyze how to to build the right content and signing part as well. For the signing part we off course need a certificate with access to the private key.

Link to part 1, part 2, part 3

NOTE AGAIN IF THE PROCESS RUNNING THE CODE DOESN’T HAVE ACCESS TO THE PRIVATE KEY YOU GET A KEYSET DOESN’T MATCH OR PRIVATE KEY COULD NOT BE FOUND ERROR WHEN TRYING TO SIGN THE MAIL.

See earlier post on howo to setup up security for certificates.

Now finaly to some code. First we gonna make a little helper method for signing the content. Also note that I use a simple helper function “GetCert()” all i does is returning the same certificate since i use the same certificate for signing and ecrypting. You should offcourse use the methode shown in part 2 of this series. My get cert is a like but just with an hardcode serial number. this should be replaced with the serial number for your certificate.

The little helper function:

public static X509Certificate2 GetCert()
{
//Sets up a new store to look for at certificat in.
X509Store localStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
localStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

try
{
//NOTE FALSE IS ONLY USED FOR TESTS SHOULD BE CHANGED TO true

X509Certificate2Collection matches =
localStore.Certificates.Find(X509FindType.FindBySerialNumber, "a0 51 bf 0a bc 4a 11 8b 41 9d 56 47 92 b2 34 6c", false);
if (matches.Count > 0)
{
return matches[0];
}
else
{
return null;
}
}
finally
{
localStore.Close();
}

}

And here is how crypting part works. The signature calculation. Note that the function takes two certifactes one for signing the mail and the certificates used for encrypting the mail. Theese two could be the same. But you might have an certificat only for signing and the you need the extra one for encrypting the mail.

</pre>
public byte[] GetSignature(string message, X509Certificate2 signingCertificate, X509Certificate2 encryptionCertificate)
 {
 byte[] messageBytes = Encoding.ASCII.GetBytes(message);

SignedCms signedCms = new SignedCms(new ContentInfo(messageBytes), true);

CmsSigner cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signingCertificate);
 cmsSigner.IncludeOption = X509IncludeOption.WholeChain;

if (encryptionCertificate != null)
 {
 cmsSigner.Certificates.Add(encryptionCertificate);
 }

Pkcs9SigningTime signingTime = new Pkcs9SigningTime();
 cmsSigner.SignedAttributes.Add(signingTime);

signedCms.ComputeSignature(cmsSigner, false);

return signedCms.Encode();
 }

With this function we can start adding new boundary to the content so it will be correct signed. This part was nesscary for me  otherwise i could either encryot the mail or sign it not both. So before we sign the mail we add som new boundaries and finaly we gonna add the calculated signature. Again this function accept the content from we made in the laste post so as input you could give the method the result from “buildcontent()”. Againg note this is build in simple function so we can got a simple reference when we wnat to encrypt the content.

</pre>
public string signed(string Content)
 {
 string signatureBoundry = "--PTBoundry=2";
 string signatureBoundry2 = "--PTBoundry=3";
 StringBuilder fullUnsignedMessageBuilder = new StringBuilder();

fullUnsignedMessageBuilder.Append("Content-Type: ");
 fullUnsignedMessageBuilder.Append("multipart/mixed;");
 fullUnsignedMessageBuilder.Append(" boundary=\"");
 fullUnsignedMessageBuilder.Append(signatureBoundry);
 fullUnsignedMessageBuilder.Append("\"\r\n");
 fullUnsignedMessageBuilder.Append("Content-Transfer-Encoding: ");

fullUnsignedMessageBuilder.Append(TransferEncoding.SevenBit);
 fullUnsignedMessageBuilder.Append("\r\n");
 fullUnsignedMessageBuilder.Append(Content);

string fullUnsignedMessage = fullUnsignedMessageBuilder.ToString();

byte[] signature = GetSignature(fullUnsignedMessage, GetCert(), GetCert());

StringBuilder signedMessageBuilder = new StringBuilder();

signedMessageBuilder.Append("--");
 signedMessageBuilder.Append(signatureBoundry2);
 signedMessageBuilder.Append("\r\n");
 signedMessageBuilder.Append(fullUnsignedMessage);
 signedMessageBuilder.Append("\r\n");
 signedMessageBuilder.Append("--");
 signedMessageBuilder.Append(signatureBoundry2);
 signedMessageBuilder.Append("\r\n");
 signedMessageBuilder.Append("Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\r\n");
 signedMessageBuilder.Append("Content-Transfer-Encoding: base64\r\n");
 signedMessageBuilder.Append("Content-Disposition: attachment; filename=\"smime.p7s\"\r\n\r\n");
 signedMessageBuilder.Append(Convert.ToBase64String(signature));
 signedMessageBuilder.Append("\r\n\r\n");

signedMessageBuilder.Append("--");
 signedMessageBuilder.Append(signatureBoundry2);
 signedMessageBuilder.Append("--\r\n");

return signedMessageBuilder.ToString();
 }

It is now posssible to return and signed message string ready to be encrypted by calling :

signed(buildcontent())

Do note the reference the tells we the content boundary start is different form the boundary for the signing part, and boundary for the signature is offcourse the same as for the signing boundary. So it is important to have acces to the different boundaries for between each steps. And when we want to encryp the content we also need the referencs for the signing boundary.

Okay with the content now signed we should be ready to encrypt the mail and send it see next post Where we also will look at how the final content should look just before it is send, This will also help one to build the mailcontent for your own purposes.

Now whe signed the mail.

Advertisement
Categories: C# Tags: ,

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: