【问题标题】:Are SQL Server encryption functions deterministic?SQL Server 加密函数是否具有确定性?
【发布时间】:2019-06-26 14:13:20
【问题描述】:

我正在学习 SQL Server 加密,我有一个关于确定性行为的问题。

SQL Server 加密函数是否具有确定性?是否取决于版本(2005,...,2017)?

我指的不是“始终加密”功能,而是像 encryptedbykey 这样的功能。

【问题讨论】:

    标签: sql-server tsql encryption encryptbykey


    【解决方案1】:

    首先,这可以很容易地进行测试。您可以将相同的值加密两次并检查输出是否相同。使用下面的代码:

    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

    地点:

    • KeyGUID := {16 字节} Key_guid。此 GUID 用作密钥的标识符,并存储在元数据中 (SELECT key_guid FROM sys.symmetric_keys)。它在解密期间用于在密钥环中找到相应的密钥。这就是为什么当我们使用DECRYPTBYKEY 时,我们不使用指定加密期间使用的密钥
    • 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.)
    • 关于你的最后一段,secure enclaves in SQL 2019 的计划引入将消除 AE 列的一些限制,例如允许使用不等式谓词对使用随机加密密钥加密的数据进行搜索。跨度>
    • @HABO 是的,是的。 Dan Guzman - 同意,你知道微软至少需要三个主要版本才能使事情正确(列存储索引、hekaton 引擎和现在的 AE)。
    • 感谢您的回复。我已经在 2017 年之前的某些 SQL Server 版本中执行了该脚本,并且所有这些版本中的函数都是非确定性的。我当然对确定性加密很感兴趣,因为我必须将某些字段加密为 first_name 或 identity_card,这些字段是您用于搜索个人登记簿的典型字段。在这种情况下,索引的可能性是可取的,并且几乎是必要的。在这种情况下,Always Encripted 不是一个有效的解决方案,因为许多代理可能以不同的方式访问数据。
    • @IgnacioJ 您可以接受这个答案并检查这​​个 - stackoverflow.com/a/52892073/1080354(如果您有任何问题,请告诉我)。
    猜你喜欢
    • 2018-09-08
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 2015-07-06
    相关资源
    最近更新 更多