This is my first post, so hope I haven't missed anything important. I'm doing a project in C# where I need to use public/private key encryption to encrypt a message and then send it over an SSL connection.
I chose to use the RSACryptoService
, as according to the documentation, that was the only asymmetric encryption scheme used for encrypting data. The problem is that I am having a lot of problems with this. (I wanted to do symmetric encryption, but that is not what my teacher want me to do, and according to him it should be easy to just determine a block size and then it should do all the work for you.) Well, so far no luck and I've tried some different approaches, but now I'm back to basics and trying again, this is my current code:
public string[] GenerateKeysToStrings(string uniqueIdentifier)
{
string[] keys;
using (var rsa = new RSACryptoServiceProvider(4096))
{
try
{
string privateKey = rsa.ToXmlString(true);
string publicKey = rsa.ToXmlString(false);
this.pki.StoreKey(publicKey, uniqueIdentifier);
keys = new string[2];
keys[0] = privateKey;
keys[1] = publicKey;
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return keys;
}
As you can see, I generate the keys and I mimmick a PKI by sending the public key to a simple class that stores it, and then the private key is written to a file
(Notice that I also have another method that does the same but stores it to an array instead, just because I wanted to test and simplify things as I get No such key exceptions
and sometimes cryptographic exceptions when I do it the way shown in the example, so I wanted to simplify it by simply storing the rsa.ToXmlString
string, as a string in an array, but no luck.)
Now I have an encrypt and decrypt method as follows:
public string Encrypt(string keyString, string message)
{
string encryptedMessage;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Load the key from the specified path
var encryptKey = new XmlDocument();
encryptKey.Load(@"C:\Test\PrivateKeyInfo.xml");
rsa.FromXmlString(encryptKey.OuterXml);
//// Conver the string message to a byte array for encryption
//// var encoder = new UTF8Encoding();
ASCIIEncoding byteConverter = new ASCIIEncoding();
byte[] dataToEncrypt = byteConverter.GetBytes(message);
byte[] encryptedData = rsa.Encrypt(dataToEncrypt, false);
//// Convert the byte array back to a string message
encryptedMessage = byteConverter.GetString(encryptedData);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return encryptedMessage;
}
Decryption:
public string Decrypt(string keyString, string message)
{
string decryptedText;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Loads the keyinfo into the rsa parameters from the keyfile
/*
var privateKey = new XmlDocument();
privateKey.Load(keyString);
*/
rsa.FromXmlString(keyString);
//// Convert the text from string to byte array for decryption
ASCIIEncoding byteConverter = new ASCIIEncoding();
var encryptedBytes = byteConverter.GetBytes(message);
//// Create an aux array to store all the encrypted bytes
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
decryptedText = byteConverter.GetString(decryptedBytes);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return decryptedText;
}
I know that this is a wall of text, but I hope you can help me out because I've been banging my head against the wall for so long now it's not funny :)
The problem is, how do I go about encrypting messages with RSA
(or any other public/private key encryption)
Here is the Test client:
public static void Main(string[] args)
{
PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
Cryptograph crypto = new Cryptograph();
string[] keys = crypto.GenerateKeysToStrings("[email protected]");
string plainText = "Hello play with me, please";
string publicKey = crypto.GetPublicKey("[email protected]");
string encryptedText = crypto.Encrypt(keys[0], plainText);
string decryptedText = crypto.Decrypt(keys[1], encryptedText);
}
As I mentioned, the string arrays are there because I wanted to eliminate bad parsing error from XML documents...
When I run the test client, if I use the private key to encrypt and public key to decrypt, I get a "Key does not exist exception" and if I do it the other way around, I get a bad data exception.
Please help me out guys, if you know of any good guide, or can tell me how to somewhat straightfoward implement public/private key encryption on string messages, please help me out.
I appreciate any help.
As a rule of thumb, we should only encrypt data as large as the RSA key length when encrypting with RSA. Although RSA is not ideal for encrypting large files, we can use it to encrypt a key file generated from the standard AES symmetric encryption.
RSA is only able to encrypt data to a maximum amount equal to your key size (2048 bits = 256 bytes), minus any padding and header data (11 bytes for PKCS#1 v1. 5 padding). As a result, it is often not possible to encrypt files with RSA directly (and RSA is not designed for this).
Simply, RSA is very resource expensive algorithm, it takes time to generate RSA keys and to perform operations on these enormous prime numbers. As the size of data increases, the process load increases and the whole thing ends up taking too much time to complete.
This is not how RSA encryption should be done.
RSA is all about math. What you encrypt is a number so it has to be of finite length and matching the RSA keypair length you're using. Further length limitations are imposed by the padding used (either PKCS#1 or OAEP).
If you want to encrypt large data with RSA you need to do it indirectly - i.e. use a symmetric key to encrypt the large data and encrypt this key using the RSA public key.
You can read about implementing this on my blog.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With