Asymmetric Key Encryption with RSA and X509

| 3 Comments | No TrackBacks

I had a requirement for a project that I am working on.  The project consists of a Windows 2003 Web Server serving up custom C# Web Services, and a public-facing LAMP [Linux, Apache, MySQL, PHP] web server.  I have certain data that I am storing in a MySQL database that must be encrypted.  Given that this is a webserver symmetric encryption does not make sense because if someone gained access to the PHP files, they would have the password to decrypt the data!!  That would be bad.

So I chose to do asymmetric encryption, thus only the Public Key would reside on the server.  The PHP scripts would encrypt the data, store it in a database, and when needed would be transmitted to the web-services server and decrypted using C#.  This proved to be a rather daunting task however. 

PHP requires either an X509 certificate, or a PEM certificate.  On the surface, .NET does neither!  The RSACryptoProviderService was able to create keys, but they were in some XML format which was incompatible with what I needed to do with PHP.

It turns out that I needed to use X509 certificates to accomplish what I needed.  Yikes, I had absolutely no idea what X509 was and how I was going to use it.  Little did I know that the internet was going to conspire against me and make finding all of the information that I needed virtually impossible.  After spending countless hours going over the MSDN, web pages, and other resources.. I finally managed to figure out what exactly needed to be done.

Following this blogpost on using Makecert I was able to create a certificate authority to sign my certificate, and create a certificate.  I installed in it in the Certificate Store, exported BOTH the Private and Public key file.  The public key I exported in BASE64 (second option) and the private key in PKCS#12 (PFX) format.  The private key is readable by .NET for the decryption.

I sent the public key to my PHP webserver.  Using the following code I was able to encrypt a string:

Now on the .NET side.. here is the code I used to decrypt the data using a private certificate file:

/// <summary>
Decrypt data
/// </summary>
/// <param name="Base64EncryptedData"></param>
/// <param name="PathToPrivateKey"></param>
/// <returns></returns>
public static string DecryptEncryptedData(stringBase64EncryptedData, stringPathToPrivateKeyFile) {
        myCertificate = newX509Certificate2(PathToPrivateKeyFile);
    } catch{
        throw newCryptographicException("Unable to open key file.");

    RSACryptoServiceProvider rsaObj;
    if(myCertificate.HasPrivateKey) {
         rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
    } else
        throw new
CryptographicException("Private key not contained within certificate.");

    if(rsaObj == null)

    byte[] decryptedBytes;
        decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);
    } catch {
        throw newCryptographicException("Unable to decrypt data.");

    //    Check to make sure we decrpyted the string
if(decryptedBytes.Length == 0)

There you have it! That's it in a nutshell. By using the X509Certificate2 class, I was able to read in the key [this reads in several key formats, by the way], then create the RSACryptoServiceProvider object and cast the .PrivateKey field into it, and perform the decryption.

- Matthew

No TrackBacks

TrackBack URL:


Good article. Thanks for posting for us .NET people :) Easy and powerful.

Very useful article thanks for sharing :).

Thanks a lot for sharing. Simple, to the point, and very useful for me :)

Leave a comment

About this Entry

This page contains a single entry by Matthew M. published on April 9, 2008 8:45 PM.

Generic C# Object Copy Function was the previous entry in this blog.

Password Protection Utility is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.