C#问题使用RSA解密来解密

时间:2016-04-10 19:05:18

标签: c# encryption rsa

Hello Stackoverflow用户,我正在进行有关RSA加密和解密的工作,并且遇到了一个棘手的问题。

使用Visual Studio我创建了一个简单的表单,其中包含2个文本框(一个用于纯文本消息,另一个用于显示加密的消息)和4个按钮(2个清除按钮用于清除相应的文本框以及加密按钮和解密按钮)

public partial class Form1 : Form
{
    //Strings to hold public & private keys
    String publicKey, privateKey; 
    UnicodeEncoding encoder = new UnicodeEncoding();

    public Form1()
    {
        RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider();
        InitializeComponent();
        privateKey = myRSA.ToXmlString(true);
        publicKey = myRSA.ToXmlString(false);
    }

    private void btnClr1_Click(object sender, EventArgs e)
    {
        txtPlain.Text = "";
        txtPlain.Refresh();
    }

    private void btnClr2_Click(object sender, EventArgs e)
    {
        txtCypher.Text = "";
        txtCypher.Refresh();
    }

    private void btnEncrypt_Click(object sender, EventArgs e)
    {
        var myRSA = new RSACryptoServiceProvider();

        //Set cryptoserviceprovider with the proper key
        myRSA.FromXmlString(publicKey);

        //Encode the data to encrypt as a byte array
        var dataToEncrypt = encoder.GetBytes(txtPlain.Text);

        //Encrypt the byte array
        var encryptedByteArray = myRSA.Encrypt(dataToEncrypt, false).ToArray();

        var length = encryptedByteArray.Count();
        var item = 0;
        var sb = new StringBuilder();

        //Change each byte in the encrypted byte array to text
        foreach(var x in encryptedByteArray)
        {
            item++;
            sb.Append(x);
            if (item < length) sb.Append(",");
        }
        txtCypher.Text = sb.ToString();
    }

    private void btnDecrypt_Click(object sender, EventArgs e)
    {
        var myRSA = new RSACryptoServiceProvider();

       //Split data into an array
        var dataArray = txtCypher.Text.Split(new char[] { ',' });

        //Convert chars to bytes
        byte[] dataByte = new byte[dataArray.Length];

        for(int i = 0; i < dataArray.Length; i++) dataByte[i] = Convert.ToByte(dataArray[i]);

        //Decrypt the byte array
        myRSA.FromXmlString(privateKey);
        var decryptedBytes = myRSA.Decrypt(dataByte, false);

        //place into cypher text box
        txtPlain.Text = encoder.GetString(decryptedBytes);
    }
}

我对加密和解密邮件没有任何问题(显然,只要它们不超过RSA密钥大小)。

所以我正在努力修改我的程序,以允许加密和解密任何大小的消息。

这是我提出的代码,允许加密任何大小(这似乎有效)

private void btnEncrypt_Click(object sender, EventArgs e)
    {
        var myRSA = new RSACryptoServiceProvider();

        //Set cryptoserviceprovider with the proper key
        myRSA.FromXmlString(publicKey);

        //Encode the data to encrypt as a byte array
        var dataToEncrypt = encoder.GetBytes(txtPlain.Text);

        //store dataLength
        int dataLength = dataToEncrypt.Length;

        //Check if dataLength > 128 
        if (dataLength > 128)
        {
            //Divide dataLength by 128 to determine how many cycles will be needed
            double numOfCycles = (dataLength / 117);
            //round up to nearest whole number
            cycles = (int)Math.Ceiling(numOfCycles);


            //for however many cycles
            for (int i = 0; i < cycles; i++)
            {
                var myByteArray = new byte[117];
                for (int j = 0; j < 117; j++)
                {
                    int currentByte = i * 117 + j;
                    myByteArray[j] = dataToEncrypt[currentByte];
                }

                var encryptedByteArray = myRSA.Encrypt(myByteArray, false).ToArray();

                var length = encryptedByteArray.Count();
                var item = 0;

                //Change each byte in the encrypted byte array to text
                foreach (var x in encryptedByteArray)
                {
                    item++;
                    sb.Append(x);
                    if (item < length) sb.Append(",");
                }
                txtCypher.Text = sb.ToString();
            }
        }
        else
        {
            var encryptedByteArray = myRSA.Encrypt(dataToEncrypt, false).ToArray();
            var length = encryptedByteArray.Count();
            var item = 0;
            var sb = new StringBuilder();

            //Change each byte in the encrypted byte array to text
            foreach(var x in encryptedByteArray)
            {
                item++;
                sb.Append(x);
            if (item < length) sb.Append(",");
            }
              txtCypher.Text = sb.ToString();   
            }
    }

这是我用来处理任何大小消息解密的代码(这是给我错误的)

 private void btnDecrypt_Click(object sender, EventArgs e)
    {
        var myRSA = new RSACryptoServiceProvider();

       //Split data into an array
        var dataArray = txtCypher.Text.Split(new char[] { ',' });

        int length = dataArray.Count();
        float numOfCycles = (length / 117);
        int cycles = (int)Math.Ceiling(numOfCycles);

        for (int i = 0; i < cycles; i++) 
        {
            byte[] dataByte = new byte[117];
            for(int j = 0; j < 117; j++)
            {
                //Convert chars to bytes
                dataByte[j] = Convert.ToByte(dataArray[ i * 117 + j ]);
            }
            //Decrypt the byte array
            myRSA.FromXmlString(privateKey);
            var decryptedBytes = myRSA.Decrypt(dataByte, false);
            txtPlain.Text += encoder.GetString(decryptedBytes);
        }
    }

抛出的错误是:

`System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll. Additional information: Bad Data.`
第133行

var decryptedBytes = myRSA.Decrypt(dataByte, false);

非常感谢任何帮助/建议!谢谢大家!

1 个答案:

答案 0 :(得分:0)

正如Luke Park所说,尝试将RSA作为链式算法通常被认为是不好的做法。它的目的是进行安全的密钥交换&#34;,这意味着加密的内容被假定为#34;是对称加密信息。

然而,如果你决定走这条路;问题是RSA-Encrypt总是产生一个长度为密钥大小的输出。您的代码假定=>&gt;中的117个字节117个字节;而事实并非如此。

由于RSA-Decrypt希望您使用RSA-Encrypt准备数据,因此它会报告&#34;错误数据&#34;因为你还没有给它一个有效的数据报(有效数据报的长度等于密钥大小)。