2

我正在使用AesCryptoServiceProviderCryptoStream加密一些数据,当我使用相同的密钥进行解密时,它似乎工作正常。但是,如果我尝试用错误的密钥解密它,我不会得到异常,只是垃圾数据。我在 .Net 文档中找不到任何说明应该发生的事情,但据此:

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

和这个:

为什么密码错误会导致“填充无效,无法删除”?

我应该得到一个 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();
        }
    }
}
4

3 回答 3

1

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

我有一个在 C# 中工作的公共域 snip-it,用于字符串的对称身份验证加密的现代示例。我尽量保持最新并进行审查。

PS 此外,尚不清楚您的盐是按域、按用户还是来自示例中的每个密文,但如果它不是您的代码中的每个密文,IV 将是可预测的,并且对于许多不适合 AES-CBC 的密文来说是相同的. 实施加密是困难的。

我还研究了一个高级加密库,即 Google Keyczar 的 C# 端口。但这对你来说可能不是很好,它只支持随机生成密钥和密钥集,然后这些密钥集可以被密码加密,但只有密钥集。高级加密框架是加密的最佳实践。

于 2013-02-01T13:37:08.050 回答
0

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

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

于 2013-02-01T13:55:21.890 回答
0

我将不得不举起双手并说虚惊一场。

我不知道周五发生了什么,但现在我得到了我所期望的——大多数情况下 CryptographicException 按预期发生。我不知道我是否只是对我的测试数据非常不走运,或者我的测试工具中是否存在我无意中修复的错误,但现在一切都按预期运行。

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

于 2013-02-04T11:51:57.487 回答