yesman
yesman

Reputation: 7838

Decrypt a byte[] signed with a private key

I have two XML files with private and public keys generated by the RSACryptoServiceProvider class. I have turned a random string into a byte array, and using the private key, I have encrypted it. But how do I use the public key to decrypt the byte[] again? Here's what I have so far:

    class Program
    {
        static void Main(string[] args)
        {
            RSACryptoServiceProvider encryptor = new RSACryptoServiceProvider();
            encryptor.FromXmlString(GetPrivateKey());


            string unencryptedString = "This string could only have been send by me.";

            byte[] unencryptedByteArray = Encoding.Unicode.GetBytes(unencryptedString);

            byte[] encryptedByteArray = encryptor.SignData(unencryptedByteArray, new SHA1CryptoServiceProvider());

            byte[] decryptedByteArray; //how do I decrypt the array again?

            string decryptedString = System.Text.Encoding.Unicode.GetString(decryptedByteArray);

            Console.WriteLine(decryptedString);

            Console.ReadKey();
        }

        private static string GetPrivateKey()
        {
            using (TextReader reader = new StreamReader(@"path to private key file generated by the ToXmlString method"))
            {
                string privateKey = reader.ReadToEnd();
                reader.Close();
                return privateKey;
            }
        }

        private static string GetPublicKey()
        {
            using (TextReader reader = new StreamReader(@"path to public key file generated by the ToXmlString method"))
            {
                string privateKey = reader.ReadToEnd();
                reader.Close();
                return privateKey;
            }
        }
    }

Upvotes: 1

Views: 17027

Answers (1)

Alex
Alex

Reputation: 21766

You can't decrypt back to the value of unencryptedString. According to the documentation, the method RSACryptoServiceProvider.SignData computes the hash value of the specified data and signs it. As hashes are non-reversible by design, you can't decrypt back to the original value.

However, you can use RSACryptoServiceProvider to encrypt and decrypt data. Below I have included an example application from the documentation on MSDN

using System;
using System.Security.Cryptography;
using System.Text;

class RSACSPSample
{

    static void Main()
    {
        try
        {
            //Create a UnicodeEncoder to convert between byte array and string.
            UnicodeEncoding ByteConverter = new UnicodeEncoding();

            //Create byte arrays to hold original, encrypted, and decrypted data.
            byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
            byte[] encryptedData;
            byte[] decryptedData;

            //Create a new instance of RSACryptoServiceProvider to generate
            //public and private key data.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {

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

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

                //Display the decrypted plaintext to the console. 
                Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
            }
        }
        catch (ArgumentNullException)
        {
            //Catch this exception in case the encryption did
            //not succeed.
            Console.WriteLine("Encryption failed.");

        }
    }

    static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
    {
        try
        {
            byte[] encryptedData;
            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {

                //Import the RSA Key information. This only needs
                //toinclude the public key information.
                RSA.ImportParameters(RSAKeyInfo);

                //Encrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
            }
            return encryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);

            return null;
        }

    }

    static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
    {
        try
        {
            byte[] decryptedData;
            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                //Import the RSA Key information. This needs
                //to include the private key information.
                RSA.ImportParameters(RSAKeyInfo);

                //Decrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
            }
            return decryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException e)
        {
            Console.WriteLine(e.ToString());

            return null;
        }

    }
}

Upvotes: 5

Related Questions