首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复Rijndael解密中的'Org.BouncyCastle.Crypto.InvalidCipherTextException:'pad块损坏‘

如何修复Rijndael解密中的'Org.BouncyCastle.Crypto.InvalidCipherTextException:'pad块损坏‘
EN

Stack Overflow用户
提问于 2019-08-01 09:50:23
回答 1查看 4.2K关注 0票数 2

我有同样的坐席Decrypt Rijndael 256 Block Size with BouncyCastle

所以我修正了那篇文章中的代码,并替换了我以前的代码

代码语言:javascript
复制
public static string Decrypt(string cipherText, string superSecretPassPhrase)
{
    if (cipherText == null)
    {
        throw new ArgumentNullException(nameof(cipherText));
    }
    // Get the complete stream of bytes that represent:
    // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
    var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
    // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
    var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
    // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
    var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
    // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
    var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

    using (var password = new Rfc2898DeriveBytes(superSecretPassPhrase, saltStringBytes, _iterations))
    {
        var keyBytes = password.GetBytes(Keysize / 8);
        using (var symmetricKey = new RijndaelManaged())
        {
            symmetricKey.BlockSize = 256;
            symmetricKey.Mode = CipherMode.CBC;
            symmetricKey.Padding = PaddingMode.PKCS7;
            using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
            {
                using (var memoryStream = new System.IO.MemoryStream(cipherTextBytes))
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        var plainTextBytes = new byte[cipherTextBytes.Length];
                        var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        memoryStream.Close();
                        cryptoStream.Close();
                        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                    }
                }
            }
        }
    }
}

新代码

代码语言:javascript
复制
public static string Decrypt(string cipherText, string superSecretPassPhrase)
{
    if (cipherText == null)
    {
        throw new ArgumentNullException(nameof(cipherText));
    }
    // Get the complete stream of bytes that represent:
    // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
    var cipherTextBytesWithSaltAndIv =  Convert.FromBase64String(cipherText);
    // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
    var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
    // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
    var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
    // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
    var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

    using (var password = new Rfc2898DeriveBytes(superSecretPassPhrase, saltStringBytes, _iterations))
    {
        var keyBytes = password.GetBytes(Keysize / 8);
        var engine = new RijndaelEngine(256);
        var blockCipher = new CbcBlockCipher(engine);
        var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
        var keyParam = new KeyParameter(keyBytes);
        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);  //Exception HERE!!!
        var final = Encoding.UTF8.GetString(finalBytes);
        return final;
    }
}

我面对的是我的一些案例(我不确定,但似乎长cipherText导致了:'pad block corrupted' Exception)。

例如

代码语言:javascript
复制
static void Main(string[] args)
{
    var superSecretPassPhrase = "Office";
    var input = @"U3/7njQjVmcahG9/PtK9fhivCU1l128UACKeBvo6d+T5XwTx+A3qxkfKZCObhaMsOJQDkLrLpAUXCw6txSRrmh5vd4iYfAfTSHzrgdtlvff0gtKfwpmzYAXdvk8tJFiFnvM7xWQlxlmybNtTYVpk1c1UCvNOcyPR2YuooxJ3FV1otIzyRLMSBEOtasV0uyCnoe79mkh54/2XrGXCsLDGpQ==";
    var result = OldStringDecryptor.Decrypt(input,superSecretPassPhrase); /*everything is ok as I expected "DjSRsJ8i7RJEdZ8ooMH9RH1p2oBV7G1zPJg6hdceULIXzF9LhHJYeAb5MCOK9D9M"*/
    var result2=
        NewBouncyCastleDecryptor.Decrypt(input,superSecretPassPhrase);//throws pad block corrupted Exception
}

我还需要在新代码中修改什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-22 09:10:09

您在DoFinal方法中使用了错误的Decrypt覆盖(检查参数名)。此外,

代之以:

代码语言:javascript
复制
var outputBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
var length = cipher.ProcessBytes(cipherTextBytes, outputBytes, 0);
var finalBytes = cipher.DoFinal(outputBytes, 0, length);

通过以下方式:

代码语言:javascript
复制
var finalBytes = cipher.DoFinal(cipherTextBytes);
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57306311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档