Using Self-signed Certificates to Encrypt Text

In my previous post on using secure sockets, I showed you how to create a self-signed certificate to secure communication using sockets, if you’ve not yet read it, you can read it from the link just cited.

Securing socket communications, however, is not the only thing you can use a self-signed certificate for. You also can use it to encrypt and decrypt text by using the normal public/private key approach. I’m not going to repeat the instructions to create a certificate here. I’ll refer you back to the previous article for that.

Once you’ve created yourself a certificate, do the usual Visual Studio thing and create yourself a console application.

Make sure you have the following usings in your ‘Program.cs’ file:

using System;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

Then, make sure that your main routine looks as follows:

public static void Main()
{
   try
   {
      X509Certificate2 myCert =
         LoadCertificate(StoreLocation.CurrentUser,
         "CN=MySslSocketCertificate");

      string myText = "This is the text I wish to encrypt";
      Console.WriteLine("UNENCRYPTED: " + myText);

      string encrypted = Encrypt(myCert, myText);

      Console.WriteLine("ENCRYPTED: " + encrypted);

      string decrypted = Decrypt(myCert, encrypted);

      Console.WriteLine("DECRYPTED: " + decrypted);
   }
   catch (Exception e)
   {
      Console.WriteLine("EXCEPTION: {0}", e.Message);
   }
}

As you can see, I’ve used the same key as in the previous article, but you don’t have to. You can create a new one in exactly the same way. Loading the certificate from the store is similar, too; the code to do that is as follows:

public static X509Certificate2
   LoadCertificate(StoreLocation storeLocation,
   string certificateName)
{
   X509Store store = new X509Store(storeLocation);
   store.Open(OpenFlags.ReadOnly);
   X509Certificate2Collection certCollection =
      store.Certificates;
   X509Certificate2 cert =
      certCollection.Cast<X509Certificate2>().FirstOrDefault
      (c => c.Subject == certificateName);
   if (cert == null)
      Console.WriteLine("NO Certificate named " +
         certificateName + " was found in your certificate store");
   store.Close();
   return cert;
}

Once we can get the certificate, we then need a couple of routines to perform the encryption and decryption, add the following to your program.cs file:

private static string Encrypt(X509Certificate2 x509, string stringToEncrypt)
{
   if (x509 == null || string.IsNullOrEmpty(stringToEncrypt))
   throw new Exception("A x509 certificate and string for encryption must be provided");

   RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.PublicKey.Key;
   byte[] bytestoEncrypt = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt);
   byte[] encryptedBytes = rsa.Encrypt(bytestoEncrypt, false);
   return Convert.ToBase64String(encryptedBytes);
}

private static string Decrypt(X509Certificate2 x509, string stringTodecrypt)
{
   if (x509 == null || string.IsNullOrEmpty(stringTodecrypt))
      throw new Exception("A x509 certificate and string for decryption must be provided");

   if (!x509.HasPrivateKey)
      throw new Exception("x509 certicate does not contain a private key for decryption");

   RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.PrivateKey;
   byte[] bytestodecrypt = Convert.FromBase64String(stringTodecrypt);
   byte[] plainbytes = rsa.Decrypt(bytestodecrypt, false);
   System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
   return enc.GetString(plainbytes);
}

At this point, you should be able to build and run the program. If all goes well, you should see something like what’s shown in Figure 1:

Cert
Figure 1: Our text encryption sample running

If you get an invalid key exception thrown while trying to run this, it’s likely you’ll need to add the key to the root store certificate. You can do this easily by opening the Microsoft Management Console and loading the certificate management snapin.

Once the MMC is loaded, export your self-signed certificate, and then re-import it by using the certificate import wizard, placing it in the root certificate store.

Alternatively, when creating the certificate using make cert, you can import it straight into the root store by using

'-ss Root'

rather than

'-ss my'

as the previous post showed.

Got a .NET question you want answered? Feel free to reach out and ask me. Drop me a comment in the form below, or hunt me down on Twitter as @shawty_ds and you’ll likely see it in a future post.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read