SQL 服务器加密函数是否具有确定性?
Are SQL Server encryption functions deterministic?
我正在学习 SQL 服务器加密,我对确定性行为有疑问。
SQL 服务器加密函数是否具有确定性?是否取决于版本 (2005,..., 2017)?
我指的不是 'Always encrypted' 功能,而是 encryptedbykey
.
等功能
首先,这个很容易测试。您可以将相同的值加密两次并检查输出是否相同。使用以下代码:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe';
CREATE CERTIFICATE [CERT_Whosebug]
WITH SUBJECT = 'example';
CREATE SYMMETRIC KEY [SK_Whosebug]
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE [CERT_Whosebug];
GO
OPEN SYMMETRIC KEY [SK_Whosebug] DECRYPTION BY CERTIFICATE [CERT_Whosebug];
SELECT EncryptByKey(Key_GUID('SK_Whosebug'), 'Whosebug');
SELECT EncryptByKey(Key_GUID('SK_Whosebug'), 'Whosebug');
DROP SYMMETRIC KEY [SK_Whosebug];
DROP CERTIFICATE [CERT_Whosebug];
DROP MASTER KEY;
因此,结果是 ENCRYPTBYKEY 函数不是确定性的。
为什么?如果不是,将很容易暴力破解。如果您对幕后发生的事情感兴趣,可以查看以下article。
基本上,输出文本是这样计算的:
CipherTextMessage := KeyGUID + EncryptionHeader + EncryptedMessage
其中:
- KeyGUID := {16 字节} Key_guid。此 GUID 用作密钥的标识符,它存储在元数据中 (SELECT key_guid FROM sys.symmetric_keys)。它在解密过程中用于在密钥环中找到相应的密钥。这就是为什么当我们使用 DECRYPTBYKEY 时我们不使用指定加密期间使用的密钥
EncryptedMessage 的计算方式如下:
EncryptedMessage := InitializationVector + _EncryptFunction(SymKey,
InitializationVector, InnerMessage)
关键是 InitializationVector
即:
InitializationVector := {1 block} the length of this field depends on
the algorithm being used. All AES family keys will be 16 bytes per
block, while the DES family keys are 8 bytes per block. Initialization
vectors are used to initialize the block algorithm. It is not intended
to be a secret, but must be unique for every call to the encryption
function in order to avoid revealing patterns.
如果您对确定性加密功能感兴趣,例如因为创建索引以优化搜索,并且由于其所有限制而不想使用 Always Encrypted,我可以告诉您如何可以使用 SQL 服务器 security hierarchy.
create/simulate 确定性加密
我正在学习 SQL 服务器加密,我对确定性行为有疑问。
SQL 服务器加密函数是否具有确定性?是否取决于版本 (2005,..., 2017)?
我指的不是 'Always encrypted' 功能,而是 encryptedbykey
.
首先,这个很容易测试。您可以将相同的值加密两次并检查输出是否相同。使用以下代码:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe';
CREATE CERTIFICATE [CERT_Whosebug]
WITH SUBJECT = 'example';
CREATE SYMMETRIC KEY [SK_Whosebug]
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE [CERT_Whosebug];
GO
OPEN SYMMETRIC KEY [SK_Whosebug] DECRYPTION BY CERTIFICATE [CERT_Whosebug];
SELECT EncryptByKey(Key_GUID('SK_Whosebug'), 'Whosebug');
SELECT EncryptByKey(Key_GUID('SK_Whosebug'), 'Whosebug');
DROP SYMMETRIC KEY [SK_Whosebug];
DROP CERTIFICATE [CERT_Whosebug];
DROP MASTER KEY;
因此,结果是 ENCRYPTBYKEY 函数不是确定性的。
为什么?如果不是,将很容易暴力破解。如果您对幕后发生的事情感兴趣,可以查看以下article。 基本上,输出文本是这样计算的:
CipherTextMessage := KeyGUID + EncryptionHeader + EncryptedMessage
其中:
- KeyGUID := {16 字节} Key_guid。此 GUID 用作密钥的标识符,它存储在元数据中 (SELECT key_guid FROM sys.symmetric_keys)。它在解密过程中用于在密钥环中找到相应的密钥。这就是为什么当我们使用 DECRYPTBYKEY 时我们不使用指定加密期间使用的密钥
EncryptedMessage 的计算方式如下:
EncryptedMessage := InitializationVector + _EncryptFunction(SymKey, InitializationVector, InnerMessage)
关键是 InitializationVector
即:
InitializationVector := {1 block} the length of this field depends on the algorithm being used. All AES family keys will be 16 bytes per block, while the DES family keys are 8 bytes per block. Initialization vectors are used to initialize the block algorithm. It is not intended to be a secret, but must be unique for every call to the encryption function in order to avoid revealing patterns.
如果您对确定性加密功能感兴趣,例如因为创建索引以优化搜索,并且由于其所有限制而不想使用 Always Encrypted,我可以告诉您如何可以使用 SQL 服务器 security hierarchy.
create/simulate 确定性加密