RSA Private Key Encryption
RSA Private Key Encryption
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.
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); // 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.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2020-12-13 What's the difference between re.DOTALL and re.MULTILINE? [duplicate]
2020-12-13 Getting number of elements in an iterator in Python
2020-12-13 What is the difference between re.search and re.match?
2018-12-13 setup in xunit