【问题标题】:c# Rsa Decryption throws "Bad Data" exceptionc# Rsa解密抛出“坏数据”异常
【发布时间】:2016-08-15 13:01:25
【问题描述】:

我正在使用微软的RSACryptoServiceProvider 类来加密/解密数据。 但是,解密函数会抛出异常“Bad Data”。 每次我使用加密/解密时都会创建提供程序类的新实例吗?

RSA 提供程序类

 static public byte[] RSAEncrypt(byte[] byteEncrypt, RSAParameters RSAInfo, bool isOAEP)
    {
        try
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.ImportParameters(RSAInfo);

                //Encrypt the passed byte array and specify OAEP padding.
                return RSA.Encrypt(byteEncrypt, isOAEP);
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
            return null;
        }
    }

    static public byte[] RSADecrypt(byte[] byteDecrypt, RSAParameters RSAInfo, bool isOAEP)
    {
        try
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096))
            {
                //Import the RSA Key information. This needs
                //to include the private key information.
                RSA.ImportParameters(RSAInfo);

                //Decrypt the passed byte array and specify OAEP padding.
                return RSA.Decrypt(byteDecrypt, isOAEP);
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.ToString());
            return null;
        }
    }
}

用法

  UnicodeEncoding ByteConverter = new UnicodeEncoding();
  RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096);
  byte[] plainPassword;
  byte[] encryptedPassword;

  plainPassword = ByteConverter.GetBytes(connectionStringPasswordTextBox.Text);
  encryptedPassword = CryptoHelper.RSAEncrypt(plainPassword, RSA.ExportParameters(false), false);
  RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096);
  byte[] decryptedPassword = CryptoHelper.RSADecrypt(Convert.FromBase64String(connectionString.password), RSA.ExportParameters(true), false);

编辑

多试几次后,异常已变为“参数不正确”。我认为这与只为 rsa 类创建一个实例有关,而不是每次使用它时都创建一个新实例。

【问题讨论】:

标签: c# encryption cryptography rsa


【解决方案1】:

RSACryptoServiceProvider(int) 构造函数生成一个新密钥(除非 CAPI 为空名称返回一个密钥;我不确定这是否可行)。因此,此代码使用一个密钥加密并尝试使用另一个密钥解密。结果的答案毫无意义,以至于引发了异常。

  • 生成一次您的密钥,并从中保存 RSAParameters。
  • 为了使您的代码更便于移植,请避免使用“RSACryptoServiceProvider”;如果可能的话,只谈 RSA。
    • 不幸的是,密钥创建是不可能的,因为 RSACryptoServiceProvider 在 KeySize 更改时不会生成新密钥。

所以你真的应该在 .NET 4.6 或更高版本上使用类似这样的东西:

public static byte[] RSAEncrypt(
    byte[] byteEncrypt,
    RSAParameters rsaInfo,
    RSAEncryptionPadding padding)
{
    try
    {
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportParameters(rsaInfo);
            return rsa.Encrypt(byteEncrypt, padding);
        }
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
}

【讨论】:

  • 加密或解密方法显示“方法不支持”。
  • 您调用的是 Encrypt(byte[], RSAEncryptionPadding) 还是 EncryptValue(byte[])?后者确实会引发 NotSupportedException。如果您没有看到采用 RSAEncryptionPadding 的那个,您可能针对的是 .NET 4.5.2 或更低版本(它是 4.6 中的新功能)。见msdn.microsoft.com/en-us/library/…msdn.microsoft.com/en-us/library/…
  • 它不允许我调用 Encrypt 方法,当我调用 EncryptValue 方法时,它会抛出 NotSupportedException
  • 对,EncryptValue 从来没有工作过。如果你不能调用新的 Encrypt(byte[], RSAEncryptionPadding) 方法,你正在编译的东西早于 4.6 (或者你正在使用单声道),在这种情况下,没有什么比你拥有的更好的了(除了避免在您不想生成新密钥时生成新密钥)。
猜你喜欢
  • 2010-12-10
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2010-11-26
  • 2015-03-16
  • 1970-01-01
相关资源
最近更新 更多