Click here to Skip to main content
11,438,007 members (51,450 online)
Click here to Skip to main content

RSA Private Key Encryption

, 4 Feb 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
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)
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));  // 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();
myRsa.LoadPrivateFromXml(@"C:\privateKey.xml");
myRsa.LoadPublicFromXml(@"C:\publicKey.xml");

// 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.

RSATesterMenu.png

RSATester.jpg

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.
  5. UnitTest project added.
  6. Generally, more elegant code (I hope..!).

Using the New Version

string secret = "My secret message";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);  // Key bits length
/*
* Skip the loading part for the RSACryptoServiceProvider will generate
* 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dudi Bedner
Software Developer WonderNet
Israel 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".

Comments and Discussions

 
SuggestionWhat about large message Lets say 100 MB of data. Pin
saqibsabir2-Jan-15 6:29
membersaqibsabir2-Jan-15 6:29 
Questionjava,security.private key Pin
Member 869680830-Dec-14 0:11
memberMember 869680830-Dec-14 0:11 
QuestionWhy no more using BigInteger from own implementation Pin
XmenWK8-Dec-14 22:57
memberXmenWK8-Dec-14 22:57 
AnswerRe: Why no more using BigInteger from own implementation Pin
Dudi Bedner22-Dec-14 0:59
memberDudi Bedner22-Dec-14 0:59 
GeneralRe: Why no more using BigInteger from own implementation Pin
Xmen WK 22-Dec-14 23:39
member Xmen WK 22-Dec-14 23:39 
GeneralRe: Why no more using BigInteger from own implementation Pin
Dudi Bedner23-Dec-14 1:13
memberDudi Bedner23-Dec-14 1:13 
GeneralRe: Why no more using BigInteger from own implementation Pin
Xmen WK 23-Dec-14 3:28
member Xmen WK 23-Dec-14 3:28 
QuestionThank you Pin
clkurtz18-Nov-14 1:06
memberclkurtz18-Nov-14 1:06 
AnswerYou're welcome Pin
Dudi Bedner22-Dec-14 0:31
memberDudi Bedner22-Dec-14 0:31 
QuestionBugs Pin
WhoCaresAboutTheName11-Aug-14 2:39
memberWhoCaresAboutTheName11-Aug-14 2:39 
Questionscenario 2 Pin
wo4baba3-Aug-14 10:02
memberwo4baba3-Aug-14 10:02 
AnswerRe: scenario 2 Pin
Dudi Bedner22-Dec-14 0:50
memberDudi Bedner22-Dec-14 0:50 
GeneralMy vote of 1 Pin
Member 89488214-May-14 6:31
memberMember 89488214-May-14 6:31 
AnswerRe: My vote of 1 Pin
Dudi Bedner10-May-14 2:00
memberDudi Bedner10-May-14 2:00 
GeneralRe: My vote of 1 [modified] Pin
Member 894882120-Dec-14 0:09
memberMember 894882120-Dec-14 0:09 
GeneralRe: My vote of 1 Pin
Xmen WK 22-Dec-14 23:49
member Xmen WK 22-Dec-14 23:49 
Question.net 4 and SQL Server 2008 CLR Pin
Hennie115-Apr-14 0:51
memberHennie115-Apr-14 0:51 
QuestionPublicDecryption False [modified] Pin
chinh sa23-Feb-14 18:03
memberchinh sa23-Feb-14 18:03 
AnswerRe: PublicDecryption False Pin
CrAcK754-Dec-14 11:37
memberCrAcK754-Dec-14 11:37 
QuestionHello Pin
KEL34-Aug-13 0:02
memberKEL34-Aug-13 0:02 
GeneralRe: Hello [modified] Pin
KEL34-Aug-13 0:15
memberKEL34-Aug-13 0:15 
QuestionPublic encryption still possible with new version? Pin
twinfoot29-Mar-13 2:19
membertwinfoot29-Mar-13 2:19 
SuggestionInteresting point. Pin
Dudi Bedner2-Apr-13 9:39
memberDudi Bedner2-Apr-13 9:39 
QuestionABE Pin
kaliprasad12313-Mar-13 1:14
memberkaliprasad12313-Mar-13 1:14 
QuestionCertificate Store X509 Pin
drice24-Feb-13 15:01
memberdrice24-Feb-13 15:01 
GeneralVery good piece of soft. Thank you. Pin
robert.com27-Jan-13 6:25
memberrobert.com27-Jan-13 6:25 
QuestionPHP Compatibility Pin
Member 97418469-Jan-13 1:12
memberMember 97418469-Jan-13 1:12 
AnswerRe: PHP Compatibility Pin
Member 894882120-Dec-14 0:04
memberMember 894882120-Dec-14 0:04 
Questiongeting some error Pin
hemantrautela27-Dec-12 2:48
memberhemantrautela27-Dec-12 2:48 
AnswerRe: geting some error Pin
Dudi Bedner27-Dec-12 11:31
memberDudi Bedner27-Dec-12 11:31 
Encoding.UTF8.GetBytes("your string to encrypt").Length
Should not exceed the length of the key,
create a RSACryptoServiceProvider object with a larger key if it does.
If this doesn't help, post the full stack trace and the string parameter.

Regards,
Dudi.
GeneralRe: geting some error Pin
hemantrautela27-Dec-12 20:46
memberhemantrautela27-Dec-12 20:46 
QuestionRSA 2048 Pin
Member 968083413-Dec-12 11:27
memberMember 968083413-Dec-12 11:27 
AnswerRe: RSA 2048 Pin
Member 968083413-Dec-12 18:05
memberMember 968083413-Dec-12 18:05 
Questiondecryption Pin
golden duck14-Sep-12 4:06
membergolden duck14-Sep-12 4:06 
Questionwrong decrypted string... Pin
Member 857509518-Apr-12 9:09
memberMember 857509518-Apr-12 9:09 
GeneralMy vote of 4 Pin
jasonkz31-Mar-12 22:26
memberjasonkz31-Mar-12 22:26 
NewsSevere vulnerability found in RSA encryption Pin
knoami4-Feb-12 23:58
memberknoami4-Feb-12 23:58 
AnswerThe last paragraph on the article [modified] Pin
Dudi Bedner8-Feb-12 0:21
memberDudi Bedner8-Feb-12 0:21 
QuestionMisc Issues Pin
abi8029-Jan-12 8:35
memberabi8029-Jan-12 8:35 
AnswerRe: Misc Issues Pin
Dudi Bedner29-Jan-12 13:31
memberDudi Bedner29-Jan-12 13:31 
GeneralRe: Misc Issues Pin
abi8030-Jan-12 8:11
memberabi8030-Jan-12 8:11 
QuestionEncryption of images of size 1024x1024 Pin
Member 852711429-Dec-11 17:58
memberMember 852711429-Dec-11 17:58 
QuestionIt simply does not work Pin
glen_waverley5-Dec-11 0:44
memberglen_waverley5-Dec-11 0:44 
BugBug Found [modified] Pin
malovicn21-Jul-11 11:12
membermalovicn21-Jul-11 11:12 
GeneralMore enhancements Pin
barrd2-Jun-11 14:35
memberbarrd2-Jun-11 14:35 
GeneralRe: More enhancements Pin
malovicn21-Jul-11 11:24
membermalovicn21-Jul-11 11:24 
GeneralRe: More enhancements Pin
CarelAgain5-Feb-12 0:01
memberCarelAgain5-Feb-12 0:01 
GeneralIt seems very buggy Pin
Member 740216628-May-11 22:40
memberMember 740216628-May-11 22:40 
GeneralMy vote of 3 Pin
smartpro12-Apr-11 2:45
membersmartpro12-Apr-11 2:45 
QuestionCA Private Key Pin
Member 768785020-Feb-11 2:08
memberMember 768785020-Feb-11 2:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150506.1 | Last Updated 4 Feb 2012
Article Copyright 2009 by Dudi Bedner
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid