【问题标题】:Bad Data exception during RSA decryptionRSA 解密期间出现错误数据异常
【发布时间】:2017-11-08 01:02:55
【问题描述】:

我正在做一个项目。加密工作正常,但在解密时,我的程序抛出“错误数据异常”。我该如何解决这个问题?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace WindowsFormsApplication2
{

    public partial class Form1 : Form
    {
        byte[] cipher;
        byte[] plain;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


        private static string Encrypt(byte[] plain)
        {
            byte[] encrypted;
          RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

                StreamReader StRe = new StreamReader("D:\\PjesaVetemPublike.xml");
                string VetemPublikeXML = StRe.ReadToEnd();
                rsa.FromXmlString(VetemPublikeXML);
                StRe.Close();
                encrypted = rsa.Encrypt(plain, true);

            return Encoding.UTF8.GetString(encrypted);
        }

        private static string Decrypt(byte[] encrypted)
        {
            byte[] decrypted;
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

                StreamReader StRe = new         
         StreamReader("D:\\PjesaPublikeDhePrivate.xml");
                string PublikeDhePrivate = StRe.ReadToEnd();
                rsa.FromXmlString(PublikeDhePrivate);
                StRe.Close();

                decrypted = rsa.Decrypt(encrypted, false);   //THE ERROR APPEARS RIGHT HERE

            return Encoding.UTF8.GetString(decrypted);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            plain = Encoding.UTF8.GetBytes(txtPlain.Text);
            txtCipher.Text = Encrypt(plain);

        }

        private void button2_Click(object sender, EventArgs e)
        {

            txtDekriptuar.Text = Decrypt(cipher);
        }
    }
}

【问题讨论】:

  • 这可能表示密钥错误。检查你的钥匙

标签: c# encryption rsa


【解决方案1】:

在其他问题中,您假设密文可以有意义地转换为 UTF-8,但这并不能保证。

如果您想加密文本并将加密内容作为文本传输/存储,您需要遵循以下模式:

加密(textIn => textOut):

  • 通过某种编码将 textIn 转换为 bytesIn。 UTF-8 很不错。
  • 将 bytesIn 加密为 bytesOut。
  • 对 bytesOut 应用无损编码。 Base64 几乎总是为此的最佳选择,并且是 .NET 内置的最佳选择。 (textOut = Convert.ToBase64String(bytesOut))。
  • 返回 textOut。

解密(textIn => textOut):

  • 应用 Encrypt 的逆变换将 textIn 转换为 bytesIn。很有可能Convert.FromBase64String
  • 将 bytesIn 解密为 bytesOut。
  • 应用文本编码转换将 bytesOut 转换为 textOut。没有什么真正说明这需要与 Encrypt 中使用的相同,但这样做可能是有意义的。

使用 UTF-8(或 ASCII 或 UCS-2 等)作为加密数据的文本表示的问题在于,加密数据可以合法地包含一个值为 0x00 的字节(或控制代码、换行符) , 等等)。虽然 .NET 在大多数情况下可以愉快地在字符串中传输嵌入的空字符,但它肯定会造成很大的混乱(并非所有语言/函数都以相同的方式处理它)。

其他有趣的角色:

  • 您的语言/功能对嵌入式0x7F(删除)有什么作用?
  • 如果将字符串存储在单行文本字段中,任何 CR 或 LF 字符会发生什么情况?如果你的程序在 Windows 上得到没有 LF 的 CR,或者没有 CR 的 LF,你的程序会做什么?
  • 带有0x13 (^S) 的 Unix 命令行可能会挂起,但它只是在等待 0x11 (^Q)。

使用什么编码来存储密文?好吧,任何可以安全地打包控制字符的东西。

【讨论】:

  • 优秀的逐步通用解决方案!非常感谢!
【解决方案2】:

假设您的密钥对是正确的,问题是您使用不同的padding schemes 进行加密和解密。

传递给RSACryptoServiceProvider#EncryptRSACryptoServiceProvider#Decrypt 的第二个参数表示是否使用OAEP。在加密期间您请求 OAEP,但在解密期间您请求 PKCS#1 v1.5 填充。这些不兼容。只需使用更安全的 OAEP。

你应该使用

decrypted = rsa.Decrypt(encrypted, true); 

【讨论】:

  • 您的私钥似乎与您的公钥不兼容。此外,RSA 不能用于加密任意数据(您需要实现 hybrid encryption)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2011-04-28
  • 2012-09-14
  • 2017-12-10
  • 2014-01-28
  • 1970-01-01
相关资源
最近更新 更多