【发布时间】:2019-06-26 14:13:20
【问题描述】:
我正在学习 SQL Server 加密,我有一个关于确定性行为的问题。
SQL Server 加密函数是否具有确定性?是否取决于版本(2005,...,2017)?
我指的不是“始终加密”功能,而是像 encryptedbykey 这样的功能。
【问题讨论】:
标签: sql-server tsql encryption encryptbykey
我正在学习 SQL Server 加密,我有一个关于确定性行为的问题。
SQL Server 加密函数是否具有确定性?是否取决于版本(2005,...,2017)?
我指的不是“始终加密”功能,而是像 encryptedbykey 这样的功能。
【问题讨论】:
标签: sql-server tsql encryption encryptbykey
首先,这可以很容易地进行测试。您可以将相同的值加密两次并检查输出是否相同。使用下面的代码:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe';
CREATE CERTIFICATE [CERT_StackOverflow]
WITH SUBJECT = 'example';
CREATE SYMMETRIC KEY [SK_StackOverflow]
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE [CERT_StackOverflow];
GO
OPEN SYMMETRIC KEY [SK_StackOverflow] DECRYPTION BY CERTIFICATE [CERT_StackOverflow];
SELECT EncryptByKey(Key_GUID('SK_StackOverflow'), 'stackoverflow');
SELECT EncryptByKey(Key_GUID('SK_StackOverflow'), 'stackoverflow');
DROP SYMMETRIC KEY [SK_StackOverflow];
DROP CERTIFICATE [CERT_StackOverflow];
DROP MASTER KEY;
所以,结果是ENCRYPTBYKEY 函数不是确定性的。
为什么?如果不是这样,暴力破解将非常容易。如果您对幕后发生的事情感兴趣,可以查看以下article。 基本上,输出文本是这样计算的:
CipherTextMessage := KeyGUID + EncryptionHeader + EncryptedMessage
地点:
EncryptedMessage 的计算方式如下:
EncryptedMessage := InitializationVector + _EncryptFunction(SymKey, InitializationVector, InnerMessage)
关键是InitializationVector,即:
InitializationVector := {1 block} 该字段的长度取决于 正在使用的算法。所有 AES 系列密钥将是 16 字节/ 块,而 DES 系列密钥是每个块 8 个字节。初始化 向量用于初始化块算法。不是有意的 是一个秘密,但对于每次调用加密必须是唯一的 功能,以避免暴露模式。
如果您对确定性加密功能感兴趣,例如为了优化搜索而创建索引,并且由于其所有限制而不想使用 Always Encrypted,我可以告诉您如何创建/使用 SQL Server security hierarchy 模拟确定性加密。
【讨论】:
GetDate() 可能会为两个调用返回相同的值。 (周末阅读:The "BUG" Heard 'Round the World.)