尝试使用错误的密钥解密时的AesCryptoServiceProvider行为

时间:2013-02-01 12:32:44

标签: c# .net encryption cryptography

我正在使用AesCryptoServiceProviderCryptoStream来加密某些数据,当我使用相同的密钥进行解密时,它似乎正常工作。但是,如果我尝试用错误的密钥解密它,我不会得到异常,只是垃圾数据。我在.Net文档中找不到任何可能发生的内容,但根据这一点:

http://books.google.co.uk/books?id=_Y0rWd-Q2xkC&pg=PA631

和此:

Why does a bad password cause "Padding is invalid and cannot be removed"?

我应该收到CryptographicException。我做错了吗?我的功能是:

public static byte[] Encrypt(byte[] data, string password, string salt, bool decrypt)
{
    SymmetricAlgorithm aes = new AesCryptoServiceProvider();
    Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
    aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);
    aes.Key = rfc2898.GetBytes(256 / 8);
    ICryptoTransform enc;
    if (decrypt) {
        enc = aes.CreateDecryptor();
    } else {
        enc = aes.CreateEncryptor();
    }
    using (enc) {
        using (MemoryStream ms = new MemoryStream()) {
            using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write)) {
                cs.Write(data, 0, data.Length);
            return ms.ToArray();
        }
    }
}

3 个答案:

答案 0 :(得分:1)

依靠填充错误不是确定密钥是否正确的好方法。您应该考虑使用Authenticated Encryption来实现此目的。

我有一个公共域剪辑 - 它适用于此Modern Examples of Symmetric Authenticated Encryption of a string.的C#,我会尽力保持最新并进行审核。

P.S。此外,还不清楚您的盐是按域,按用户还是按样本的密文,但如果您的代码中不是每个密文,则IV将是可预测的,并且对于许多不对AES-CBC有益的密文也是如此。实施加密很难。

我还参与了一个高级加密库,C# port of Google Keyczar。但这可能不适合您,它只支持随机生成密钥和密钥集,然后这些密钥集可以进行密码加密,但只能使用密钥集。高级加密框架是加密的最佳实践。

答案 1 :(得分:0)

如果您在解密时没有设置填充,则解密方法无法识别垃圾。将填充设置为PKCS#7进行加密和加密,解密方法可能会识别垃圾。

为了充分保证,您将需要身份验证,正如jbtule所说。要在一个数据传递中包含身份验证和加密,请使用GCM mode。对于单独的身份验证,请使用HMAC

答案 2 :(得分:0)

我将不得不把手放在这里并说出虚假警报。

我不知道星期五发生了什么,但现在我得到了我所期望的 - 大部分时间CryptographicException按预期发生。我不知道我是不是对我的测试数据非常不走运,或者我的测试工具中是否有一个我无意中修复过的错误,但它现在都表现得像预期的那样。

顺便说一下,我做了一个快速的实证测试,验证了rossum的1/256数字,但这对我来说是可以接受的。在一般情况下,我完全接受关于HMAC等的其他评论,但我正在做的是测试工具