【发布时间】:2018-02-26 17:38:31
【问题描述】:
在我们的项目中,我们使用以下方法在存储之前对重要数据进行加密/解密。传入字节的大小始终为 32。请看一下:
public static string Encrypt(byte[] data, string pass)
{
using (var algorithm = new RijndaelManaged())
{
algorithm.Padding = PaddingMode.PKCS7;
var salt = new byte[32];
new Random().NextBytes(salt);
using (var rng = new Rfc2898DeriveBytes(pass, salt, 3072))
{
algorithm.Key = rng.GetBytes(algorithm.KeySize / 8);
algorithm.IV = rng.GetBytes(algorithm.BlockSize / 8);
using (var oms = new MemoryStream())
{
using (var ims = new MemoryStream(data))
{
var encryptor = algorithm.CreateEncryptor();
var cs = new CryptoStream(oms, encryptor, CryptoStreamMode.Write);
ims.CopyTo(cs);
cs.FlushFinalBlock();
}
oms.Flush();
var target = new byte[oms.Length + salt.Length];
oms.ToArray().CopyTo(target, 0);
salt.CopyTo(target, oms.Length);
return Convert.ToBase64String(target);
}
}
}
}
public static byte[] Decrypt(string data, string pass)
{
var allbytes = Convert.FromBase64String(data);
var salt = new byte[32];
var databytes = new byte[allbytes.Length - salt.Length];
Array.Copy(allbytes, databytes.Length, salt, 0, salt.Length);
Array.Copy(allbytes, 0, databytes, 0, databytes.Length);
using (var algorithm = new RijndaelManaged())
{
algorithm.Padding = PaddingMode.PKCS7;
using (var rng = new Rfc2898DeriveBytes(pass, salt, 3072))
{
algorithm.Key = rng.GetBytes(algorithm.KeySize / 8);
algorithm.IV = rng.GetBytes(algorithm.BlockSize / 8);
using (var oms = new MemoryStream())
{
using (var ims = new MemoryStream(databytes))
{
var decryptor = algorithm.CreateDecryptor();
using (var cs = new CryptoStream(ims, decryptor, CryptoStreamMode.Read))
{
cs.CopyTo(oms);
}
}
return oms.ToArray();
}
}
}
}
这段代码在所有情况下都很好用。但是在客户环境中,我们在解密期间得到了 47 个字节而不是 32 个字节。经过一番调查,我意识到当使用不正确的密码短语时可能会发生这种行为(与加密不同,但在另一个字节组合中可以很好地解密)。但客户非常确定密码是正确的。可能是环境配置(Windows 或 .Net 更新、安全配置等)导致此类问题的情况? 感谢您的帮助。
更新。添加了示例代码以证明密码不正确。加密字符串包含从 1 到 32 的 32 个字节,并使用密码“p@ssW0rd”加密。如果使用正确的密码解密它,我们将得到 32 个字节,但如果使用“p4ssW7rd”,结果将包含 47 个字节。
var password = "p@ssW0rd";
var incorrectPassword = "p4ssW7rd";
var encryptedData = "gP/MV6S09UYWc0pMgkkIqEdg204rToV/FQLpvktArWjAlIqjpbiPg5YX9zhPA9/gRuSbNtU5nyBKst54041uGeDNKSYJYvJc1UKZrMcqVFw=";
var decryptedData = Decrypt(encryptedData, password);
var incorrectDecryptedData = Decrypt(encryptedData, incorrectPassword);
Console.WriteLine("Decrypted size: {0}, incorrect size: {1}", decryptedData.Length, incorrectDecryptedData.Length);
在任何其他情况下(密码不正确除外)都可能得到错误的解密数据?
【问题讨论】:
-
如果解密不正确,你会得到错误。问题在于: var target = new byte[oms.Length + salt.Length];这意味着其中一个长度是错误的。
-
没有解密代码是不可能知道发生了什么的。
-
@Gusman 有解密码,请更新页面
-
@jdweng 谢谢,但我确信长度是正确的。代码适用于许多其他情况
-
代码按预期工作,您的客户一定是做错了什么。您的客户是否真的使用您发布的代码来解密数据?
标签: c# .net encryption cryptography aes