Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSACryptoServiceProvider initialize with own public key and private key

I'm trying to initialize RSACryptoServiceProvider with my own public and private keys.

As far as I could research, the way to do this is to call the constructor with

RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(cspParams);

cspParams as shown above. However, when I look at the msdn example on the use of it: http://msdn.microsoft.com/en-us/library/ca5htw4f.aspx

I don't see any place where they set the private or public keys. Only using a KeyContainer. When I create an RSACryptoServiceProvider without a cspParam, then it is by default set to only use a Public key. I notice this when I check the PublicOnly variable on the class itself and it is a read only variable.

My question is how do I initialize this class and then set my own private and public keys. The server will be using the private key and the client will have the public key.

What I found out is that creating an RSAParameter object and setting the .Exponent and .Modulus parameters on it as the public and private variables respectively.

But I'm getting a "Missing Private Key" error since I believe the RSACryptoServiceProvider isn't initialized with the correct constructor.

Below is some of my code. Don't worry about BigInteger class, it's just an experiment. Even if I use it or not, I get the same error.

//Create a UnicodeEncoder to convert between byte array and string.
UnicodeEncoding ByteConverter = new UnicodeEncoding();

byte[] dataToEncrypt = ByteConverter.GetBytes(password);
byte[] encryptedData;
byte[] decryptedData;

//RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters rsap = new RSAParameters();

BigInteger n = new BigInteger("19579160939939334264971282204525611731944172893619019759209712156289528980860378672033164235760825723282900348193871051950190013953658941960463089031452404364269503721476236241284015792700835264262839734314564696723261501877759107784604657504350348081273959965406686529089170062268136253938904906635532824296510859016002105655690559115059267476786307037941751235763572931501055146976797606538425089134251611194500570922973015579287289778637105402129208324300035518642730384616767241853993887666288072512402523498267733725021939287517009966986976768028023180137546958580922532786773172365428677544232641888174470601681", 10);

BigInteger e = new BigInteger("65537", 10);

//rsap.Modulus = ByteConverter.GetBytes(publicKey);
rsap.Exponent = e.getBytes();
rsap.Modulus = n.getBytes();
  /*rsap.Exponent = ByteConverter.GetBytes(publicKey);
    rsap.D = ByteConverter.GetBytes(publicKey);
    rsap.DP = ByteConverter.GetBytes(publicKey);
    rsap.DQ = ByteConverter.GetBytes(publicKey);
    rsap.P = ByteConverter.GetBytes(publicKey);
    rsap.Q = ByteConverter.GetBytes(publicKey);
    rsap.InverseQ = ByteConverter.GetBytes(publicKey);*/

using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
    //RSA.PublicOnly = false;

    RSA.ImportParameters(rsap);

    Debug.Log ("PublicOnly: " + RSA.PublicOnly);

    Debug.Log (rsap.Modulus.Length);
    //Debug.Log (RSA.ToString());
        //Pass the data to ENCRYPT, the public key information  
        //(using RSACryptoServiceProvider.ExportParameters(false), 
        //and a boolean flag specifying no OAEP padding.
        //encryptedData = RSACSPSample.RSAEncrypt(dataToEncrypt, rsap, false);
        encryptedData = RSACSPSample.RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false), false);


        Debug.Log ("encryptedData: " + encryptedData);
        //Display the decrypted plaintext to the console. 
        //Debug.Log("Decrypted plaintext: " + ByteConverter.GetString(""));

        //Pass the data to DECRYPT, the private key information  
        //(using RSACryptoServiceProvider.ExportParameters(true), 
        //and a boolean flag specifying no OAEP padding.
        decryptedData = RSACSPSample.RSADecrypt(encryptedData, RSA.ExportParameters(true), false);
}


//encryptedData = RSACSPSample.RSAEncrypt(dataToEncrypt, rsap, false);

//if (encryptedData != null) {
    password = ByteConverter.GetString(decryptedData);
//}
like image 678
C0D3 Avatar asked Nov 30 '12 22:11

C0D3


1 Answers

The fields are horribly named and it is confusing you. The Exponent field is really the public exponent for a public key. The private exponent for a private key is the D field.

It is not your fault that MSDN documentation sucks.

like image 122
President James K. Polk Avatar answered Sep 28 '22 09:09

President James K. Polk