gpt4 book ai didi

.net - 如何获得 C# 和 SQL2k8 AES 加密之间的兼容性?

转载 作者:行者123 更新时间:2023-12-04 02:18:01 24 4
gpt4 key购买 nike

我在两列上进行了 AES 加密:其中一列存储在 SQL Server 2000 数据库;另一个存储在 SQL Server 2008 数据库。

由于第一列的数据库 (2000) 没有用于加密/解密的 native 功能,我们决定在应用程序级别使用 .NET 类为两者执行加密逻辑。

但是由于第二列的数据库(2008)允许这种功能,我们希望使用数据库功能使数据迁移更快,因为SQL 2k中的数据迁移比这一秒小得多,而且会持续更长时间超过 50 小时,因为是在应用程序级别制作的。

我的问题从此时开始:使用相同的 key ,我在加密一个值时没有达到相同的结果,也没有相同的结果大小。

下面我们有双方的完整逻辑..当然我没有展示关键,但其他一切都是一样的:

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 对称 key ,我可以这样做吗?

但即使没有在 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 向加密的内容添加了一堆粘性物质,包括随机初始化向量。来自 Michael Cole 的书“Pro T-SQL 2005 Programmer's Guide”(尽管 2008 以同样的方式这样做):

    When SQL Server encrypts by symmetric key, it adds metadata to the encrypted result, as well as padding, making the encrypted result larger (sometimes significantly larger) than the unencrypted plain text. The format for the encrypted result with metadata follows this format:

    • The first 16 bytes of the encrypted result represent the GUID of the symmetric key used to encrypt the data
    • The next 4 bytes represent the version number, currently hard-coded as "01000000".
    • The next 8 bytes for DES encryption (16 bytes for AES encryption) represent the randomly generated initialization vector.
    • The next 8 bytes are header information representing the options used to encrypt the data. If the authenticator option is used, this header information includes a 20-byte SHA1 hash of the authenticator, making the header information 28 bytes in length.
    • The last part of the encrypted data is the actual data and padding itself. For DES algorithms, the length of this encrypted data will be a multiple of 8 bytes. For AES algorithms, the length will be a multiple of 16 bytes.

    关于.net - 如何获得 C# 和 SQL2k8 AES 加密之间的兼容性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2822592/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com