我对两列进行了 AES 加密:其中一列存储在 SQL Server 2000数据库中;另一个存储在 SQL Server 2008数据库中。
由于第一列的数据库 (2000) 没有用于加密/解密的本机功能,因此我们决定在应用程序级别使用 .NET 类对两者进行加密逻辑。
但是由于第二列的数据库(2008)允许这种功能,我们希望使用数据库功能的数据迁移更快,因为SQL 2k中的数据迁移比这一秒要小得多,并且会持续更长的时间超过 50 小时,因为是在应用程序级别制作的。
我的问题从这一点开始:使用相同的密钥,我在加密一个值时没有得到相同的结果,也没有相同的结果大小。
下面我们有双方的完整逻辑。当然我没有显示关键,但其他一切都是一样的:
private byte[] RijndaelEncrypt(byte[] clearData, byte[] Key)
{
var memoryStream = new MemoryStream();
Rijndael algorithm = Rijndael.Create();
algorithm.Key = Key;
algorithm.IV = InitializationVector;
var criptoStream = new CryptoStream(memoryStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
criptoStream.Write(clearData, 0, clearData.Length);
criptoStream.Close();
byte[] encryptedData = memoryStream.ToArray();
return encryptedData;
}
private byte[] RijndaelDecrypt(byte[] cipherData, byte[] Key)
{
var memoryStream = new MemoryStream();
Rijndael algorithm = Rijndael.Create();
algorithm.Key = Key;
algorithm.IV = InitializationVector;
var criptoStream = new CryptoStream(memoryStream, algorithm.CreateDecryptor(), CryptoStreamMode.Write);
criptoStream.Write(cipherData, 0, cipherData.Length);
criptoStream.Close();
byte[] decryptedData = memoryStream.ToArray();
return decryptedData;
}
这是 SQL 代码示例:
open symmetric key columnKey decryption by password = N'{pwd!!i_ll_not_show_it_here}'
declare @enc varchar(max)
set @enc = dbo.VarBinarytoBase64(EncryptByKey(Key_GUID('columnKey'), 'blablabla'))
select LEN(@enc), @enc
这个 varbinaryToBase64 是一个经过测试的 sql 函数,我们用来将 varbinary 转换为我们用来在 .net 应用程序中存储字符串的相同格式。
C# 中的结果是: eg0wgTeR3noWYgvdmpzTKijkdtTsdvnvKzh+uhyN3Lo=
SQL2k8 中的相同结果是: AI0zI7D77EmqgTQrdgMBHAEAAACyACXb+P3HvctA0yBduAuwPS4Ah3AB4Dbdj2KBGC1Dk4b8GEbtXs5fINzvusp8FRBknF15Br2xI1CqP0Qb/M4w
我只是还没有得到我做错了什么。
你有什么想法?
编辑:我认为至关重要的一点:我的 C# 代码中有一个初始化向量,16 个字节。此 IV 未设置为 SQL 对称密钥,我可以这样做吗?
但即使没有用 C# 填充 IV,我也会得到非常不同的结果,无论是内容还是长度。