Sql server 加密列作为主键的一部分,按不工作分组、排序、搜索开销
我在表中有一个主键列,它在早期阶段被设计为未加密列。现在,我们计划使用SQL Server内置的细粒度加密将此列作为加密列。 我使用以下示例代码进行测试 我对同一列有以下要求Sql server 加密列作为主键的一部分,按不工作分组、排序、搜索开销,sql-server,sql-server-2008,sorting,encryption,grouping,Sql Server,Sql Server 2008,Sorting,Encryption,Grouping,我在表中有一个主键列,它在早期阶段被设计为未加密列。现在,我们计划使用SQL Server内置的细粒度加密将此列作为加密列。 我使用以下示例代码进行测试 我对同一列有以下要求 该列在许多其他表中广泛用作外键 在应用程序中,同一列作为复合主键/非聚集索引的一部分在多个表中建立索引 需要基于通配符搜索来搜索列 按两个方向对列进行排序 我面临的问题是,当我加密值时,每次都会得到不同的值 我无法在同一列上进行分组 当需要执行基于通配符的搜索或排序时,需要取消列中存储的所有数据的加密 有没有更好的方法来解
CREATE DATABASE Bank
GO
USE Bank
GO
CREATE TABLE Account (
AccountId int NOT NULL IDENTITY(1,1) PRIMARY KEY,
AccountNumber varchar(50),
EncryptedAccountNumber varbinary(128) )
GO
-----------------
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd'
-----------------
CREATE CERTIFICATE BankCert
WITH SUBJECT = 'Account Numbers';
GO
-----------------
CREATE SYMMETRIC KEY BankAccountKey
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE BankCert;
GO
--Encryption-----------------
OPEN SYMMETRIC KEY BankAccountKey
DECRYPTION BY CERTIFICATE BankCert; --insert original and encrypted values
INSERT INTO Account
VALUES ('123456789', ENCRYPTBYKEY(KEY_GUID('BankAccountKey'), '123456789')),
('987654321', ENCRYPTBYKEY(KEY_GUID('BankAccountKey'), '987654321'))
SELECT * FROM Account
--Decryption-----------------------------------------------------------
OPEN SYMMETRIC KEY BankAccountKey
DECRYPTION BY CERTIFICATE BankCert;
GO
--list original and decrypted values
SELECT
AccountNumber,
EncryptedAccountNumber,
LEN(EncryptedAccountNumber) AS Size,
CONVERT(varchar, DECRYPTBYKEY(EncryptedAccountNumber)) AS DecryptedAccountNumber
FROM Account
数据库中的所有列级加密都是不确定和随机的。您可以使用SQL Server 2016 Always Encrypted并将其配置为确定性加密,但如果基数较低,您将面临有人使用驱动程序创建帐户号码哈希表并破坏加密的风险。最好将其从主键中删除,并将其作为外键引用的所有表上的列删除,这样它将仅位于一个表上并进行加密。至于搜索,您可以在解密之前在最后四位数字上创建一个哈希来缩小结果范围。这将减少工作量。也许您不应该将帐号用作外键?帐号不是真正的列。我用这个例子解释了这个场景。也许你不应该把那个列用作外键?谢谢。你的解决方案会奏效的。但这是一个现有的系统。如果避免将该列作为外键,则需要使用另一个未加密的列在其他表中进行映射。这需要在存储过程中进行巨大的更改。