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()
      X509Certificate2 myCert =

      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);
   X509Certificate2Collection certCollection =
   X509Certificate2 cert =
      (c => c.Subject == certificateName);
   if (cert == null)
      Console.WriteLine("NO Certificate named " +
         certificateName + " was found in your certificate store");
   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:

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.

This article was originally published on November 13th, 2015

About the Author

Peter Shaw

As an early adopter of IT back in the late 1970s to early 1980s, I started out with a humble little 1KB Sinclair ZX81 home computer. Within a very short space of time, this small 1KB machine became a 16KB Tandy TRS-80, followed by an Acorn Electron and, eventually, after going through many other different machines, a 4MB, ARM-powered Acorn A5000. After leaving school and getting involved with DOS-based PCs, I went on to train in many different disciplines in the computer networking and communications industries. After returning to university in the mid-1990s and gaining a Bachelor of Science in Computing for Industry, I now run my own consulting business in the northeast of England called Digital Solutions Computer Software, Ltd. I advise clients at both a hardware and software level in many different IT disciplines, covering a wide range of domain-specific knowledge—from mobile communications and networks right through to geographic information systems and banking and finance.

Related Articles

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date