Asymmetric Encryption with RSACryptoServiceProvider

9 בינואר 2011

one comment

Traditional symmetric cryptography is all about hiding a secret using an algorithm and a key. The same key is used for encryption and decryption.

Asymmetric encryption does much more. In Asymmetric encryption there are two key: one is kept secret (private) and the other is distributed (public). Both keys are mathematically the same – What makes the public key public is the fact that it was distributed.

To perform a full cycle both keys are required (i.e. encryption with one key and decryption with the other).

There are two possible scenarios:

  1. "Send a secret" : Encrypt some data with the public key and send it to the one who has the private key. Only she can decrypt the secret.
  2. "Proof of origin" : Encrypt some data with your private and send it to anyone who has your public. Assuming that "everyone" has your public it means that everyone can read your data. What you gained from the encryption is the fact that anyone who decrypted your data is absolutely certain that you are the source of the data because only the holder of the private key could have encrypted it.

Asymmetric encryption in .Net is extremely simple as I will demonstrate here. (I do not know why the samples published by Microsoft are so long and complicated)

To obtain public and private key you can wrap them in X.509 certificate. You can put it in a file (cer, pfx) or install it in the certificate store. Certificates can be created using Certmgr.exe , IIS manager or plenty of other tools.

It is also possible to create special xml strings from certificates that will hold the private and public keys.

The Class System.Security provides us to execute Asymmetric Cryptography is called: RSACryptoServiceProvider and it is very simple to use.

Remember: Asymmetric encryption is expensive. It cannot be used for large data! In the next post I will show how to use symmetric encryption together with Asymmetric encryption to handle large data. 

public byte[] EncryptAsyncPublic(byte[] data, X509Certificate2 certificate)

{

   try

   {              

       RSACryptoServiceProvider rsa =
               certificate.PublicKey.Key as RSACryptoServiceProvider;

 

       return rsa.Encrypt(data, true);

   }

   catch (Exception ex)

   {

         …
        
return null;

   }

}

public byte[] DecrypyAsyncPrivate(byte[] cipher,
                                  X509Certificate2 certificate)

{

   try

   {              

       RSACryptoServiceProvider rsa = 
              
certificate.PrivateKey as RSACryptoServiceProvider;

 

        return rsa.Decrypt(cipher, true);

   }

   catch (Exception ex)

   {

         …
        
return null;

   }

}

As you can see I implemented the first scenario. It happens that RSACryptoServiceProvider does not allow to execute the second scenario as is. If you will try to encrypt with the private and decrypt with the public you will get an exception! What you are trying to do is to prove to the world that you are the origin of the data. To do that RSACryptoServiceProvider provides digital signature methods.

 public byte[] SignPrivate(byte[] data, X509Certificate2 certificate)

{

   try

   {             

        RSACryptoServiceProvider rsa =
                certificate.PrivateKey as RSACryptoServiceProvider;

 

        return rsa.SignData(data, new SHA1CryptoServiceProvider());

   }

   catch (Exception ex)

   {

         …
        
return null;

   }

}

public bool VerifySinatutePublic(byte[] data
                           
byte[] signature, X509Certificate2 certificate)

{

    if ((data == null) || (signature == null))

        return false;

 

    try

    {               

        RSACryptoServiceProvider rsa =
                  
certificate.PublicKey.Key as RSACryptoServiceProvider;

 

        return rsa.VerifyData(data,
                             new SHA1CryptoServiceProvider(), signature);               

    }

    catch (Exception ex)

   {

         …
        
return false;

   }

}

        

 

Enjoy – Security is fun !

 

Manu

Add comment
facebook linkedin twitter email

Leave a Reply to Juan Flores Cancel Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Juan Flores30 במאי 2011 ב 11:08

    Hi, Ive read your article and its very usefull. I was wondering if youve tried this type of data digital signature methods whene the certificate (.cer file) has an associated (.key file) that holds the private key.

    Thank you.

    Reply