Bill Software Engineer
Bill Software Engineer

Reputation: 7782

How do I set the public and private key on RSAParameters to use for RSACryptoServiceProvider?

I read some tutorials online, and generated a public and private key, but how do I set them to be used in C#? Here is what I have:

        string publicKey = "...";
        string privateKey = "....";
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
        byte[] encryptedData;
        byte[] decryptedData;
        string decrptedStr = "";
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) {
            RSAParameters myRSAParameters = RSA.ExportParameters(true);
            myRSAParameters.Modulus = ByteConverter.GetBytes(publicKey);
            myRSAParameters.Exponent = ByteConverter.GetBytes(privateKey);
            encryptedData = RSAEncrypt(dataToEncrypt, myRSAParameters, false);
            decryptedData = RSADecrypt(encryptedData, myRSAParameters, false);
            decrptedStr = ByteConverter.GetString(decryptedData);
        }

Here are the encrypt / decrypt function that I copied strait from M$ website:

    static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding) {
        try {
            byte[] encryptedData;
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) {
                RSA.ImportParameters(RSAKeyInfo);
                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
            }
            return encryptedData;
        } catch (CryptographicException e) {
            Console.WriteLine(e.Message);

            return null;
        }

    }

    static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding) {
        try {
            byte[] decryptedData;
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) {
                RSA.ImportParameters(RSAKeyInfo);
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
            }
            return decryptedData;
        } catch (CryptographicException e) {
            Console.WriteLine(e.ToString());

            return null;
        }

    }

Upvotes: 3

Views: 15440

Answers (1)

Iridium
Iridium

Reputation: 23721

There are a number of problems here. You don't indicate the encoding of your public/private keys, but I can be sure that regardless of the encoding, simply getting the byte equivalent of the Unicode encoded string via ByteConverter.GetBytes(...) is not going to work. These should be the byte-array equivalent of the numeric RSA parameters.

The second problem is your interpretation of the "public" and "private" keys. The public key is not (just) the modulus, and the private key is not the exponent. The public key is comprised of the modulus and the (public) exponent (the Exponent property of the RSAParameters type, and the private key is the modulus and the private exponent (the D property of the RSAParameters type). However, in order to be used for decryption, the RSAParameters imported into the RSACryptoServiceProvider must also have the DP, DQ and InverseQ properties set (P and Q may also be required though I've not tested this).

Again, without knowing the encoding used in your public/private keys, I can't give any further details as to how to extract the appropriate values for populating the necessary properties of RSAParameters.

Upvotes: 3

Related Questions