Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Extension Methods Using RSA

0.00/5 (No votes)
4 May 2009 2  
Example of creating Extension Methods that encrypt string values.

Introduction

This article will hopefully give you a simple example of creating your own .NET Extension Methods. I'm a big fan of sample code, but very often, you get huge examples trying to show you every possible scenario of how something is done. I really prefer simple code, so I have intentionally kept this project small and very narrow in scope. While I do show two ways of encrypting and decrypting strings, you can use the "Registry Key" way without knowing anything about RSA or creating private/public keys.

Background

In a previous job, we used encryption for user names and passwords, but had to call a separate DLL method to do all the work. With .NET 3.0, it's much easier to extend the functionality of an existing (even .NET built-in types) type instead of creating additional DLLs. This article will not go into the details of using the RSACryptoServiceProvider object, but does have some well commented code if you're looking for some example code.

Using the code

You can use this code without knowing anything about RSACryptoServiceProvider by selecting the radio buttons that use "Reg Key" instead of "Use Xml". If you do have RSA private/public key in XML files, then you can use the "Use Xml" radio button. Just make sure you specify the correct file when encrypting/decrypting. The example code is built using Visual Studio 2008, and is written using C#. This code is not written to be object oriented, and does contain duplicate code so it is easier to follow.

Why create Extension Methods

So why should you use Extension Methods? Well, say you have an Interface that has already been implemented by some client, and now you have specification changes where you need to add some functionality to it; even worse, you have to add default logic. Everyone knows that Interfaces do not contain logic, only signatures, so now, you have to jump through hoops to either change the Interface over to an abstract class and get the client to fix their code, or add some new logic that is not associated with the original Interface and have this ugly code out there.

Another scenario where you want to create an Extension Method is shown here. You want to extend some existing functionality which you have no control over. This article shows how to add RSA encryption/decryption to any string object without knowing jack about RSA!

Steps to begin creating your own Extension Methods

It's really simple to start. First, create a standard library class file. Modify the signature of the class to be static, add static methods, and add a reference to your project for the new DLL. For the most part, this is it. There aqre some minor changes to the method signatures which we will cover in the sample code below, but this is easy stuff. For the code posted here, I am going to leave out the validation checks for brevity, but the downloadable code does contain it. I'm also only going to show the code that uses a Registry key for encryption/decryption.

The library class I created is called ExtensionMethods, and contains a class called StringExtensionMethods:

//Nothing special about this - just a standard static class
public static class StringExtensionMethods
{

    //Almost a standard static method just the first parameter is different
    //the keyword "this" tells what type of type you are extending
    //so the "this string" means we want
    //this method to be used by System.String types 
    public static string EncryptStringUsingRegistryKey(this string encryptValue, 
                                                       string publicKey)
    {
   
       // This is the variable that will be returned to the user
       string encryptedValue = string.Empty;

       // Create the CspParameters object which is used to create the RSA provider
       // without it generating a new private/public key.
       // Parameter value of 1 indicates RSA provider
       // type - 13 would indicate DSA provider
       CspParameters csp = new CspParameters(1);

       // Registry key name containing the RSA private/public key
       csp.KeyContainerName = publicKey;

       // Supply the provider name
       csp.ProviderName = "Microsoft Strong Cryptographic Provider";

       try
       {
          //Create new RSA object passing our key info
          RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
    
          // Before encrypting the value we must convert it over to byte array
          byte[] bytesToEncrypt = System.Text.Encoding.UTF8.GetBytes(encryptValue);

          // Encrypt our byte array. The false parameter has to do with 
          // padding (not to clear on this point but you can
          // look it up and decide which is better for your use)
          byte[] bytesEncrypted = rsa.Encrypt(bytesToEncrypt, false);
    
          // Extract our encrypted byte array into a string value to return to our user
          encryptedValue = Convert.ToBase64String(bytesEncrypted);
       }
       catch (CryptographicException cex)
       {
          Console.WriteLine(cex.Message);
       }
       catch (Exception ex)
       {
          Console.WriteLine(ex.Message);
       }

        return encryptedValue;
    }

    public static string DecryptStringUsingRegistryKey(this string 
                         decryptValue, string privateKey)
    {

       // This is the variable that will be returned to the user
       string decryptedValue = string.Empty;

       // Create the CspParameters object which is used to create the RSA provider
       // without it generating a new private/public key.
       // Parameter value of 1 indicates RSA provider
       // type - 13 would indicate DSA provider
       CspParameters csp = new CspParameters(1);

       // Registry key name containing the RSA private/public key
       csp.KeyContainerName = privateKey;

       // Supply the provider name
       csp.ProviderName = "Microsoft Strong Cryptographic Provider";

       try
       {
          //Create new RSA object passing our key info
          RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);

          // Before decryption we must convert this ugly string into a byte array
          byte[] valueToDecrypt = Convert.FromBase64String(decryptValue);

          // Decrypt the passed in string value -
          // Again the false value has to do with padding
          byte[] plainTextValue = rsa.Decrypt(valueToDecrypt, false);

          // Extract our decrypted byte array into
          // a string value to return to our user
          decryptedValue = System.Text.Encoding.UTF8.GetString(plainTextValue);
       }
       catch (CryptographicException cex)
       {
          Console.WriteLine(cex.Message);
       }
       catch (Exception ex)
       {
          Console.WriteLine(ex.Message);
       }

       return decryptedValue;
    }
}

The code above is very well commented, so I won't go over it again, but just remember that if you use the "Use XML" radio button, change the path to the private/public file depending on which operation you are doing. So, to use this code, all you need to do is compile it, add a reference to the DLL, and set a "usings" to your code. The actual line of code to call the method would look like

string valueToEncrypt = "Hello World";
string encryptedValue = valueToEncrypt.EncryptStringUsingRegistryKey("SomeKey");

Remember, the "SomeKey" value is any string you want to use. The RSACryptoSerivceProvider will create a key for you.

Well, I hope this helps you out in understanding Extension methods.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here