【问题标题】:C# Issue Using RSA Decryption To Decrypt使用 RSA 解密进行解密的 C# 问题
【发布时间】:2016-04-10 19:05:17
【问题描述】:

您好 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);

任何帮助/建议将不胜感激!谢谢大家!

【问题讨论】:

  • RSA 的使用不应超过大致的密钥大小位。如果您需要加密大量数据,请生成一次性 AES 密钥并使用 RSA 对其进行加密。

标签: c# encryption rsa


【解决方案1】:

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

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

由于 RSA-Decrypt 预计您已经使用 RSA-Encrypt 准备了数据,它会报告“错误数据”,因为您没有给它一个有效的数据报(一个有效的数据报的长度应该等于密钥大小)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 2010-11-17
    • 1970-01-01
    相关资源
    最近更新 更多