如何在 SQL 服务器中对大值使用 AES 加密?

How to use AES encryption for large values in SQL Server?

我有一个 SQL 服务器 table tbl 具有架构

ID int,
LongText varbinary(max)

而我在inserting/fetching记录时encrypt/decryptLongText有以下功能。

用于加密:

CREATE FUNCTION Encrypt
(  
    @ValueToEncrypt varchar(max)  
)  
RETURNS varbinary(max)  
AS  
BEGIN  
    -- Declare the return variable here  
    DECLARE @Result varbinary(max)  

    SET @Result = EncryptByKey(Key_GUID('My_Encryption_Symmetric_Key'), @ValueToEncrypt)  

    -- Return the result of the function  
    RETURN @Result  
END

用于解密:

CREATE FUNCTION Decrypt
(  
    @ValueToDecrypt varbinary(max)  
)  
RETURNS varchar(max)  
AS  
BEGIN  
    -- Declare the return variable here  
    DECLARE @Result varchar(max)  
    SET @Result = DecryptByKey(@ValueToDecrypt)  

    -- Return the result of the function  
    RETURN @Result  
END

在插入和获取记录时,我按如下方式调用这些函数:

用于插入:

--Open symmetric keys
INSERT INTO tbl 
VALUES (1, Encrypt('some long text here'))

要获取:

--Open symmetric keys
SELECT ID, Decrypt(LongText) 
FROM tbl

现在,当我尝试在 table 中插入值时,对于较大的值,我得到一个错误

String or binary data would be truncated.
The statement has been terminated.

消息可以理解的较大值会发生这种情况。我在某处读到 EncryptByKey/DecryptByKey 有 8000 字节的限制。是什么导致了这个问题?如果是,是否有任何我可以使用的解决方法或替代方法?如果否,那么我在这里做错了什么?对于我的生活,我无法弄清楚问题是什么。

Is it what is causing this problem? If Yes, is there any workaround or alternative approach that I can use?

是的,所有版本都是这样。不幸的是,周围的工作不是很容易接受,它将输入分解成小于 8000 字节最大值的大小,并分段加密它们。有趣的是 none 这些功能得到了增强,但是 hashbytes 在 2016 年得到了增强以消除 8k 限制。

2008 年或 2012 年的另一个主要替代方案是使用 CLR 为您执行此操作,如果您希望它保留在数据库中的话。

最后是 "put it in the application" 替代方案,这肯定需要更改应用程序代码。

数据库内部或外部

这确实提出了一个扩展问题,即加密或解密应该在数据库内部还是在不同的 layer/tier 上完成。每种方式都有争论,但更安全的方式是不将密钥保存在数据库中。对此的主要论点是让 DBA 或系统管理员无法查看数据。

在SQL Server 2016中,试图通过添加Always Encrypted来解决这个问题。虽然它不能直接回答您的问题,因为它添加的功能比需要的多得多,但如果您决定去 2016 年,它也可以作为一个可能的替代品。