Click here to Skip to main content
15,922,419 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:
Hi
I'm trying to encrypt and decrypt some data with RSA. I'm having problems in creating my own public and private keys and use them. This is what I did so far

I create an RSACryptoServiceProvider and a CspParameters because Im storing my keys into a key container:

CspParameters cp = new CspParameters();
cp.KeyContainerName = stContainerName; //stContainerName is a string

// 256 bytes RSA key pair
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048, cp);


Then I retrieve the public RSA key with this. I use a XmlDocument to handle the RSA Key Data

XmlDocument xmlDoc = new XmlDocument();
//true is for retrieve both the public and private RSA key
xmlDoc.InnerXml = rsa.ToXmlString(true);

XmlNodeList xmlPublicModulus = xmlDoc.GetElementsByTagName("Modulus");
XmlNodeList xmlPublicExp = xmlDoc.GetElementsByTagName("Exponent");


After that i try to encrypt and decrypt some data. I declare a new RSACryptoServiceProvider which will have the public key info.

string stDataToEncrypt = "Hey there";
string stDeencryptedData;
byte[] btEncryptedData;

//Getting the Modulus and exp from XML Data
byte[] publicModulus = Encoding.ASCII.GetBytes(xmlPublicModulus[0].InnerText);
byte[] publicExp = Encoding.ASCII.GetBytes(xmlPublicExp[0].InnerText);

//Setting Up the public key            
RSAParameters publicRSAKeyInfo = new RSAParameters();            publicRSAKeyInfo.Modulus = publicModulus;
publicRSAKeyInfo.Exponent = publicExp;

//Creating the Public Key - I think this is wrong...
RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider(2048);
rsaPublic.ImportParameters(publicRSAKeyInfo);

//Encrypting data. Im assuming that if I encrypt with the 
//RSACryptoServiceProvider rsa it will do it with the private key
btEncryptedData= rsa.Encrypt(Encoding.ASCII.GetBytes(stDataToEncrypt ),false);

//Decrypting data. Im using the RSACryptoServiceProvider rsaPublic, which has the
//public key data. HERE I GOT AN EXCEPTION
stDeencryptedData= Encoding.ASCII.GetString(rsaPublic.Decrypt(btDatoEncriptado,false));

Console.WriteLine("datoDesencriptado: " + datoDesencriptado);


I got an exception: incorrect key. Cheking the parameters of the rsaPublic object, the KeyLenght property is 2752. This parameter in rsa object is 2048. This tells me that I am doing somethin wrong.

What I understand of RSACryptoServiceProvider object is that it creates a RSA Key pair. So if I want to give someone else the public key, and I want to encrypt or decrypt with the private key, this is what I have to do

Any help would be appreciated and excuse my english

Regards

Iván
Posted

How this schema would possible work?! No! You completely miss the whole idea of the Public-key Cryptography.

Read my lips: :-)
You always encrypt with one key but decrypt with another one!
To understand why it works this way, please read this: http://en.wikipedia.org/wiki/Public-key_cryptography[^].
Just follow the logic of exchange between Alice and Bob.

It's all based on the idea of one-way function: http://en.wikipedia.org/wiki/One-way_function[^].

See also: http://en.wikipedia.org/wiki/RSA[^].

—SA
 
Share this answer
 
v3
Comments
blackhattrick 10-Apr-11 16:20pm    
Hi SAKryukov. Thank you for your feedback.

Im trying to create a RSA Key pair(public and private), and use the private key for encrypt data and decrypt it with the public key (I'm going to use this in a kind of file-signature schema). I think this is OK with the RSA standars

For what I have learned about generating RSA keys with C#, RSACryptoServiceProvider gives a pair of keys, a public one and a private one. So what I tried to do was create those 2 keys, getting the public key by creating a new RSACryptoServiceProvider and assigning it a public modulus and a public exponent from the first RSACryptoServiceProvider. Then I tried to encrypt some data with the first RSACryptoServiceProvider object, assuming that it will do it with the private key, and deencrypting the data with the second RSACryptoServiceProvider object.

If this is not the best way to create those 2 keys and do all the encryption/deencryption process that I need, could anyone suggest me something else? Thank you in advance.

Regards

Iván
Sergey Alexandrovich Kryukov 10-Apr-11 20:53pm    
Iván, I already answered. Use my note and read the article at the references I provide.
I never faced any problems. You're encrypting with the keys not, service providers; the service providers really provide only the three algorithms: key pair generation, encryption and decryption.

If you still see the problem, make another code, this time using different keys for different directions; if you have exception, dump and report it exactly: show it stack and lines of source code where it goes.
--SA
blackhattrick 11-Apr-11 12:35pm    
Thank you SAKryukov

Searching through codeproject, I found this article:
http://www.codeproject.com/KB/security/PrivateEncryption.aspx

As I feared, RSACryptoServiceProvider does not allow to encrypt data with the private key, and for porpuses of siging data, I would have to use some signin - verify methods of some other classes. This article implements a new RSA class for encrypting with the private key generated from the RSACryptoServiceProvider.

Im going to try this. I will post my results and if it works, Im going to close this tread as solutioned.

Thanks you for your help

Ivan
Sergey Alexandrovich Kryukov 11-Apr-11 13:51pm    
Good it it helps, but you did not have to read the article to figure this out. The RSA use is fairly straightforward.
Anyway, please notify when and if you get it right.
--SA
The solution I found

Use the RSA classes provided in:
RSA Private Key Encryption[^]

I modified some methods in order to get the private and public keys from a strings instead of a xml file, because I want to use the .NET Key containers feature.

These are how my main methods looks:

public static void CreateRSAKeys(string stContainerName)
{
    // Create the CspParameters object and set the key container
    // name used to store the RSA key pair.
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = stContainerName;

    // Create a new instance of RSACryptoServiceProvider that accesses
    // the key container MyKeyContainerName.
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048,cp);
    Console.WriteLine("RSA KEY Created: " + rsa.ToXmlString(false));
}

public static void EncryptWithPrivateKey(string stContainerName)
{
    RSAEncryption myRsaPrivateEncryption = new RSAEncryption();

    string stDataToEncrypt = "Hey There";
    byte[] btEncryptedData;
    byte[] btDeencryptedData;
    string stDeencryptedData;

    // Create the CspParameters object and set the key container
    // name used to store the RSA key pair.
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = stContainerName;

    // Create a new instance of RSACryptoServiceProvider that accesses
    // the key container MyKeyContainerName.
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048, cp);

    //Loading the private  and the key into the MyRSA object
    myRsaPrivateEncryption.LoadPrivateFromString(rsa.ToXmlString(true));
    btEncryptedData = myRsaPrivateEncryption.PrivateEncryption(Encoding.ASCII.GetBytes(stDataToEncrypt));
    btDeencryptedData = myRsaPrivateEncryption.PublicDecryption(btEncryptedData);
    stDeencryptedData = Encoding.ASCII.GetString(btDeencryptedData );

    Console.WriteLine(stDeencryptedData);
}


Solved! :)
 
Share this answer
 
v3

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900