Vic*_*ues 11 .net encryption aes sql-server-2008
我在两列上进行了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;
}
Run Code Online (Sandbox Code Playgroud)
这是SQL Code示例:
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
Run Code Online (Sandbox Code Playgroud)
这个varbinaryToBase64是一个经过测试的sql函数,我们用它来将varbinary转换为我们用来在.net应用程序中存储字符串的相同格式.
C#中的结果是: eg0wgTeR3noWYgvdmpzTKijkdtTsdvnvKzh + uhyN3Lo =
SQL2k8中的相同结果是: AI0zI7D77EmqgTQrdgMBHAEAAACyACXb + P3HvctA0yBduAuwPS4Ah3AB4Dbdj2KBGC1Dk4b8GEbtXs5fINzvusp8FRBknF15Br2xI1CqP0Qb/M4w
我只是没有得到我做错了什么.
你有什么想法?
编辑:我认为有一点至关重要:我的C#代码有一个初始化向量,16个字节.这个IV没有设置在SQL对称密钥上,我可以这样做吗?
但即使没有在C#中填充IV,我的内容和长度也会得到非常不同的结果.
我要看几件事:
确保明文的内容和编码完全相同.IIRC,流默认为UTF-8,而如果你的VarBinaryToBase64
函数采用nvarchar参数,它将是Unicode.
确保两种加密算法使用相同的块大小.在SQL中,您可以在调用时确定算法CREATE SYMMETRIC KEY
.如果未指定算法,则使用AES256.在.NET中使用RijndaelManaged
,我相信默认的块大小是128,但你可以将它设置为256(如果使用Aes
该类,则不能).
我要查找的最后一件事是SQL Server如何处理您在修订后的文章中提到的初始化向量.我想说它使用了这个authenticator
参数,但这是一个疯狂的猜测.
编辑
我离开了.鉴于我发现的内容,您不能使用.NET类来解密由SQL Server的内置加密加密的文本,因为SQL Server会为加密的内容添加一堆goo,包括随机初始化向量.来自Michael Cole的书"Pro T-SQL 2005程序员指南"(尽管2008年也是这样):
当SQL Server通过对称密钥加密时,它会将元数据添加到加密结果以及填充,从而使加密结果比未加密的纯文本更大(有时更大).带元数据的加密结果的格式遵循以下格式:
- 加密结果的前16个字节表示用于加密数据的对称密钥的GUID
- 接下来的4个字节代表版本号,目前硬编码为"01000000".
- DES加密的下一个8字节(AES加密为16字节)表示随机生成的初始化向量.
- 接下来的8个字节是表示用于加密数据的选项的标题信息.如果使用authenticator选项,则此头信息包括验证器的20字节SHA1散列,使得头信息的长度为28个字节.
- 加密数据的最后一部分是实际数据和填充本身.对于DES算法,此加密数据的长度将是8个字节的倍数.对于AES算法,长度将是16个字节的倍数.
归档时间: |
|
查看次数: |
8025 次 |
最近记录: |