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.

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


  • Missing Methods

    Posted by Jeff Bowman on 12/26/2015 12:44am

    You've not indicated where you're getting the methods Encrypt() and Decrypt(). They don't appear in your previous article either. Thanks, Jeff Bowman Fairbanks, Alaska

    • RE: Missing Methods

      Posted by Shawty on 01/12/2016 12:34pm

      Hey Jeff, thanks for noticing that, let me investigate.

  • Regarding trust for self-signed certificates

    Posted by Eugene Mayevski on 11/16/2015 01:35am

    Thank you for a great job. Yet it's important to amend the articles with detailed information about how such self-signed certificates should be trusted and revoked. Without trust self-signed certificates are barely useful (especially in TLS communications). And building the trusting and validation procedures is more complicated than the rest of the code you are providing. Without proper trust and validation of certificates TLS communications are subject to man-in-the-middle attacks, and in case of encryption key exchange becomes an another hard-to-solve problem.

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Protect Your Business against Today's Rapidly Growing Threats Your business, employees, partners, and customers are depending more and more on network connectivity, and protecting data and infrastructure has moved to the top of the IT agenda. You can't arm yourself against today's rapidly increasing threats unless you understand how they work. Read this ebook to learn more about the top 10 DNS attacks that can target your external and internal DNS infrastructure, the impact they can have on the DNS server …

Most Popular Programming Stories

More for Developers

RSS Feeds

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