12,691,231 members (29,935 online)
alternative version

242.2K views
157 bookmarked
Posted

RSA Private Key Encryption

, 4 Feb 2012 CPOL
 Rate this:
How to encrypt data using a private key in .NET.

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)
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));  // Private Key
File.WriteAllText(@"C:\publicKey.xml", rsa.ToXmlString(false));  // Public Key

// Then, you can load those files to RSAEncryption instance:
RSAEncryption myRsa = new RSAEncryption();

// Once the keys are loaded (if you load a private key, there is no need to
// load the public one) you can start Encrypt / Decrypt data
// using Private / Public keys.
byte[] message = Encoding.UTF8.GetBytes("My secret message");
byte[] encryptMsg = myRsa.PrivateEncryption(message);

byte[] decryptMsg = myRsa.PublicDecryption(encryptMsg);
string originalMsg = Encoding.UTF8.GetString(decryptMsg);
// returns "My secret message"```

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:

1. Bug fix: Added random padding to support 0 bytes prefix data.
2. Uses the new .NET 4 "`BigInteger`" struct for math support.
3. Extension methods implementation: the only class instance needed is `RSACryptoServiceProvider`.
4. Better Exceptions and error handling.
6. Generally, more elegant code (I hope..!).

Using the New Version

```string secret = "My secret message";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);  // Key bits length
/*
* random Private / Public keys pair, that you can save later with
* rsa.ToXmlString(true);
*
string key = "private or public key as xml string";
rsa.FromXmlString(key);
*/
// Convert the string to byte array
byte[] secretData = Encoding.UTF8.GetBytes(secret);

// Encrypt it using the private key:
byte[] encrypted = rsa.PrivareEncryption(secretData);

// Decrypt it using the public key
byte[] decrypted = rsa.PublicDecryption(encrypted);
string decString = Encoding.UTF8.GetString(decrypted);  // And back to string
Assert.AreEqual("My secret message", decString);```

History

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

Share

 Software Developer WonderNet Israel
I speak three languages: C#, Hebrew and English...
Programming is my work, my hobby and my second love.
I work for an Israeli company named "WonderNet" that deal with digital signature solutions,
combined with Biometrics hand written signature (on a Wacom tablet).
We develop web application as well as client desktop ones,
using the .NET framwork: ASP.NET, C#, SQL-Server and more.
Cryptography is my "thing" since I lay my hand on Simon Singh work of art "The Code Book".

You may also be interested in...

 Pro

 Re: Why no more using BigInteger from own implementation Dudi Bedner23-Dec-14 1:13 Dudi Bedner 23-Dec-14 1:13
 Re: Why no more using BigInteger from own implementation Xmen WK 23-Dec-14 3:28 Xmen WK 23-Dec-14 3:28
 Thank you clkurtz18-Nov-14 1:06 clkurtz 18-Nov-14 1:06
 You're welcome Dudi Bedner22-Dec-14 0:31 Dudi Bedner 22-Dec-14 0:31
 Re: Bugs Franc Morales14-Feb-16 0:04 Franc Morales 14-Feb-16 0:04
 scenario 2 wo4baba3-Aug-14 10:02 wo4baba 3-Aug-14 10:02
 Re: scenario 2 Dudi Bedner22-Dec-14 0:50 Dudi Bedner 22-Dec-14 0:50
 My vote of 1 Member 89488214-May-14 6:31 Member 8948821 4-May-14 6:31
 Re: My vote of 1 Dudi Bedner10-May-14 2:00 Dudi Bedner 10-May-14 2:00
 Re: My vote of 1 Member 894882120-Dec-14 0:09 Member 8948821 20-Dec-14 0:09
 Re: My vote of 1 Xmen WK 22-Dec-14 23:49 Xmen WK 22-Dec-14 23:49
 .net 4 and SQL Server 2008 CLR Hennie115-Apr-14 0:51 Hennie1 15-Apr-14 0:51
 PublicDecryption False chinh sa23-Feb-14 18:03 chinh sa 23-Feb-14 18:03
 Re: PublicDecryption False CrAcK754-Dec-14 11:37 CrAcK75 4-Dec-14 11:37
 Hello KEL34-Aug-13 0:02 KEL3 4-Aug-13 0:02
 Re: Hello KEL34-Aug-13 0:15 KEL3 4-Aug-13 0:15
 Public encryption still possible with new version? twinfoot29-Mar-13 2:19 twinfoot 29-Mar-13 2:19
 Interesting point. Dudi Bedner2-Apr-13 9:39 Dudi Bedner 2-Apr-13 9:39
 Certificate Store X509 drice24-Feb-13 15:01 drice 24-Feb-13 15:01
 Very good piece of soft. Thank you. robert.com27-Jan-13 6:25 robert.com 27-Jan-13 6:25
 PHP Compatibility Member 97418469-Jan-13 1:12 Member 9741846 9-Jan-13 1:12
 Re: PHP Compatibility Member 894882120-Dec-14 0:04 Member 8948821 20-Dec-14 0:04
 geting some error hemantrautela27-Dec-12 2:48 hemantrautela 27-Dec-12 2:48
 Re: geting some error Dudi Bedner27-Dec-12 11:31 Dudi Bedner 27-Dec-12 11:31
 Re: geting some error hemantrautela27-Dec-12 20:46 hemantrautela 27-Dec-12 20:46
 RSA 2048 Member 968083413-Dec-12 11:27 Member 9680834 13-Dec-12 11:27
 Re: RSA 2048 Member 968083413-Dec-12 18:05 Member 9680834 13-Dec-12 18:05
 decryption golden duck14-Sep-12 4:06 golden duck 14-Sep-12 4:06
 wrong decrypted string... Member 857509518-Apr-12 9:09 Member 8575095 18-Apr-12 9:09
 My vote of 4 jasonkz31-Mar-12 22:26 jasonkz 31-Mar-12 22:26
 Severe vulnerability found in RSA encryption knoami4-Feb-12 23:58 knoami 4-Feb-12 23:58
 The last paragraph on the article Dudi Bedner8-Feb-12 0:21 Dudi Bedner 8-Feb-12 0:21
 Misc Issues abi8029-Jan-12 8:35 abi80 29-Jan-12 8:35
 Re: Misc Issues Dudi Bedner29-Jan-12 13:31 Dudi Bedner 29-Jan-12 13:31
 Re: Misc Issues abi8030-Jan-12 8:11 abi80 30-Jan-12 8:11
 Encryption of images of size 1024x1024 Member 852711429-Dec-11 17:58 Member 8527114 29-Dec-11 17:58
 It simply does not work glen_waverley5-Dec-11 0:44 glen_waverley 5-Dec-11 0:44
 Bug Found [modified] malovicn21-Jul-11 11:12 malovicn 21-Jul-11 11:12
 More enhancements barrd2-Jun-11 14:35 barrd 2-Jun-11 14:35
 Re: More enhancements malovicn21-Jul-11 11:24 malovicn 21-Jul-11 11:24
 Re: More enhancements CarelAgain5-Feb-12 0:01 CarelAgain 5-Feb-12 0:01
 It seems very buggy Member 740216628-May-11 22:40 Member 7402166 28-May-11 22:40
 My vote of 3 smartpro12-Apr-11 2:45 smartpro 12-Apr-11 2:45
 CA Private Key Member 768785020-Feb-11 2:08 Member 7687850 20-Feb-11 2:08
 rsacryptoserviceprovider FreeRider18-Feb-11 6:55 FreeRider1 8-Feb-11 6:55
 ok, I've handled it :) Just had to add padding bytes to data beeing encoded! FreeRider19-Feb-11 4:41 FreeRider1 9-Feb-11 4:41
 Re: ok, I've handled it :) Just had to add padding bytes to data beeing encoded! abi8029-Jan-12 7:07 abi80 29-Jan-12 7:07
 Interoperability with OpenSSL wknopf19-Jan-11 14:21 wknopf 19-Jan-11 14:21
 Last Visit: 31-Dec-99 19:00     Last Update: 17-Jan-17 2:57 Refresh 12 Next »