如何在 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 年,它也可以作为一个可能的替代品。
我有一个 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 年,它也可以作为一个可能的替代品。