## RSA Introduction

The RSA (Rivest, Shamir, Adleman) encryption algorithm uses two Keys: Private and Public.

#### Scenario A

Suppose Alice wants to send a message to Bob (for his eyes only!). She can encrypt the message using the RSA algorithm with Bob's Public
Key, which is not a secret (that's why they call it Public…). Once the message is encrypted, nobody can decrypt it, except the one holding the matching Private Key (that is Bob).

#### Scenario B

The reverse is also true: if Alice would encrypt the message using her own **Private Key**, Bob (and Eve, and everyone who can access this "encrypted" message) can
decrypt it using Alice's Public Key. So, if everybody can decrypt it, what's the point in encrypting the message with a Private Key in the
first place? Well, there is a point if Bob wants to make sure that the message has been written by Alice and not by someone else (Eve?).

## .NET RSACryptoServiceProvider

The .NET Framework implements the RSA algorithm in the `RSACryptoServiceProvider`

class. The instance of this class lets you create Key pairs, encrypt
**using a public key**, decrypt **using a private key** (as in the first scenario), sign (sort of the second scenario, but not exactly), and verify the signature.

The Sign method accepts a message (as byte array) and creates a signature for this particular data. In the second scenario, Alice can write a message to Bob,
and use this method to get a signature with her own private key. Then, she can send the message to Bob as is (unencrypted) with the signature. To verify the writer ID (Alice), Bob
will use the `Verify`

method with Alice's public key as: `Verify(aliceMessage, aliceSignature)`

, and he will get "`true`

" if this is the
original message written and signed by Alice, or "`false`

" if even one bit has been changed since. This is one useful
implementation of private key encryption, but sometimes it's just too complicated. You might want to send just a little message so the
receiver can decrypt it and be sure it's from you, without the need to sign and send him both components.

## RSA Private Key Encryption

Unfortunately, the `RSACryptoServiceProvider`

class does not provide you this option, so I wrote my own implementation of the RSA algorithm using
the basics of the `RSACryptoServiceProvider`

in conjunction with Chew Keong
TAN's class: `BigInteger`

(http://www.codeproject.com/KB/cs/biginteger.aspx). At a low level,
the RSA algorithm is about implementing mathematical equations on huge (huge) integers, so the `BigInteger`

class is really essential. I couldn't have done it myself.

## Using the RSAEncryption Class

The class has six main methods:

void LoadPublicFromXml(string publicPath)
void LoadPrivateFromXml(string privatePath)
byte[] PrivateEncryption(byte[] data)
byte[] PublicEncryption(byte[] data)
byte[] PrivateDecryption(byte[] encryptedData)
byte[] PublicDecryption(byte[] encryptedData)

I believe the method names are self explanatory. First, you have to create a private / public key pair, using the .NET `RSACryptoServiceProvider`

class.
To do that, you just create an instance of this class and then call the appropriate methods, like this:

void LoadPublicFromXml(string publicPath)
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
File.WriteAllText(@"C:\privateKey.xml", rsa.ToXmlString(true));
File.WriteAllText(@"C:\publicKey.xml", rsa.ToXmlString(false));
RSAEncryption myRsa = new RSAEncryption();
myRsa.LoadPrivateFromXml(@"C:\privateKey.xml");
myRsa.LoadPublicFromXml(@"C:\publicKey.xml");
byte[] message = Encoding.UTF8.GetBytes("My secret message");
byte[] encryptMsg = myRsa.PrivateEncryption(message);
byte[] decryptMsg = myRsa.PublicDecryption(encryptMsg);
string originalMsg = Encoding.UTF8.GetString(decryptMsg);

## WinForms Tester Application

To help you get started with the `RSAEncryption`

and the `RSACryptoServiceProvider`

classes, I wrote a WinForms tester application that uses those classes.
All you need to do is just play with it a little and read the code-behind.

## Update: New Version

The new implementation of the RSA Private Encryption has a few advantages:

- Bug fix: Added random padding to support 0 bytes prefix data.
- Uses the new .NET 4 "
`BigInteger`

" struct for math support.
- Extension methods implementation: the only class instance needed is
`RSACryptoServiceProvider`

.
- Better Exceptions and error handling.
- UnitTest project added.
- Generally, more elegant code (I hope..!).

## Using the New Version

string secret = "My secret message";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
byte[] secretData = Encoding.UTF8.GetBytes(secret);
byte[] encrypted = rsa.PrivareEncryption(secretData);
byte[] decrypted = rsa.PublicDecryption(encrypted);
string decString = Encoding.UTF8.GetString(decrypted);
Assert.AreEqual("My secret message", decString);

## History

- 4
^{th} August, 2009: Initial post.
- 5
^{th} August, 2009: Improved code to check the state of the uploaded keys before trying to make the encryption / decryption.
- 1
^{st} February, 2012: Improved and fixed new version.