.net 5 中的 RijndaelManaged 解密不起作用

RijndaelManaged Decryption in .net 5 not working

我在 .net 框架中有以下代码来解密一些信息,它工作正常。我的任务是将此代码升级到 .net 5,但相同的代码无法正常工作。

.net 框架中的当前代码工作正常

private static string DecryptStringFromBytes(string cypherText, byte[] key)
{
    byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

    if (key == null || key.Length <= 0)
        throw new ArgumentNullException("key");

    string plaintext;
    using (var rijAlg = new RijndaelManaged())
    {
        rijAlg.BlockSize = 256;
        rijAlg.Key = key;
        rijAlg.Mode = CipherMode.CBC;
        rijAlg.Padding = PaddingMode.Zeros;
        rijAlg.IV = ASCIIEncoding.ASCII.GetBytes(MD5(MD5(_encryptionKey)));

        ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
        using (var msDecrypt = new MemoryStream(cipherTextBytes))
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        using (var srDecrypt = new StreamReader(csDecrypt))
            plaintext = srDecrypt.ReadToEnd();
    }
    return plaintext;
}

private static string MD5(string testString)
{
    byte[] asciiBytes = ASCIIEncoding.ASCII.GetBytes(testString);
    byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
    string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
    return hashedString;
}

我在 .net 5 中尝试使用相同的代码时出现以下错误。 “在此实现中 BlockSize 必须为 128”

当我将上述代码中的块大小更改为 128 时,错误消失了,但解密后的文本都是乱码(不是可读格式)。

我对此做了一些研究,我意识到 .net 核心尚不支持 256 块大小,解决方法是将它与 Bouncy Castle 库一起使用。我对此进行了一些 google 搜索,在查看了一些示例后,我将代码更新为以下

public static string DecryptFromBouncyCastle(string cipherText, byte[] key)
{
    byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
    if (key == null || key.Length <= 0)
        throw new ArgumentNullException("key");

    var ivStringBytes = new byte[16];

    var engine = new RijndaelEngine(256);
    var blockCipher = new CbcBlockCipher(engine);
    var cipher = new PaddedBufferedBlockCipher(blockCipher, new ZeroBytePadding());
    var keyParam = new KeyParameter(key);
    var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
    cipher.Init(false, keyParamWithIV);
    var outputBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
    var length = cipher.ProcessBytes(cipherTextBytes, outputBytes, 0);
    var finalBytes = cipher.DoFinal(outputBytes, 0, length);
    var resultText = Encoding.UTF8.GetString(finalBytes);
    return resultText;
}

private static string MD5(string testString)
{
    byte[] asciiBytes = ASCIIEncoding.ASCII.GetBytes(testString);
    byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
    string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
    return hashedString;
}

这段代码没有给我任何错误,但我看到部分解密工作正常。我看到了 30% 的解密文本,剩下一些垃圾字符。

我不太熟悉 encryption/decryption 的内部结构,我很难理解问题出在哪里。这可能是一个小问题,但我想不通。

如果有人可以查看此代码并让我知道我的代码的问题所在或建议是否有其他更好的替代解决方案,我将不胜感激。

必须修改 IV 和 DoFinal() 调用:

var ivStringBytes = ASCIIEncoding.ASCII.GetBytes(MD5(MD5(_encryptionKey)));     // Fix 1
...
length += cipher.DoFinal(outputBytes, length);                                  // Fix 2
var resultText = Encoding.UTF8.GetString(outputBytes, 0, length);               // Fix 3

请注意,静态 IV 是不安全的。此外,AES 应该优于具有 256 位块大小的 Rijndael。