我正在使用 SQL Server 2017 的测试环境中验证使用对称密钥加密数据是否能够满足我们的需求。我已经使用下面的对称密钥成功加密和解密数据,但是当我在同一服务器上测试密钥的恢复时,它不会解密最初加密的数据。我确信我只是遗漏了一块拼图,但我看不到它是什么。
我使用以下内容创建了证书和密钥:
CREATE CERTIFICATE TestCert
ENCRYPTION BY PASSWORD = 'QGTkj3E$NvySXU4x7ens'
WITH SUBJECT = 'Testing encryption by Certificate',
EXPIRY_DATE = '20251231';
CREATE SYMMETRIC KEY TestSymKey
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE TestCert;
然后我使用以下方法备份了证书:
BACKUP CERTIFICATE TestCert
TO FILE = N'c:\Backup\TestCert.cer'
WITH PRIVATE KEY
( FILE = N'c:\Backup\TestCert.pvk'
, ENCRYPTION BY PASSWORD = N'AReallyStr0ngK#y4You'
, DECRYPTION BY PASSWORD = N'QGTkj3E$NvySXU4x7ens'
)
;
然后我删除了对称密钥,然后删除了证书。我使用以下命令成功重新创建了证书和密钥:
CREATE CERTIFICATE TestCert
FROM FILE = N'c:\Backup\TestCert.cer'
WITH PRIVATE KEY
(
FILE = N'c:\Backup\TestCert.pvk',
DECRYPTION BY PASSWORD = N'AReallyStr0ngK#y4You',
ENCRYPTION BY PASSWORD = 'QGTkj3E$NvySXU4x7ens'
);
CREATE SYMMETRIC KEY TestSymKey
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE TestCert;
我可以使用相同的 select 语句(没有错误),但解密的数据返回 NULL。如果我使用新密钥更新表中的加密数据,则 select 语句会成功提取解密的数据。
ALTER PROCEDURE [dbo].[spGetData]
@uid nvarchar(128),
@CertKey as varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @sqlOpenCert AS NVARCHAR(MAX);
SET NOCOUNT ON;
SET @sqlOpenCert = 'OPEN SYMMETRIC KEY TestSymKey DECRYPTION BY CERTIFICATE TestCert WITH PASSWORD = '''+@CertKey+'''';
EXEC sp_executesql @sqlOpenCert;
select [DateEncValue], CONVERT(nvarchar, DecryptByKey([DateEncValue])) as dateDec, TextEncValue, CONVERT(nvarchar, DecryptByKey(TextEncValue)) as textDec
from tblEncryptTest
where encryptid = @uid
CLOSE SYMMETRIC KEY TestSymKey;
END
该表设置有 4 列。 2 个用于存储原始值(测试目的),两个用于存储加密值。
CREATE TABLE [dbo].[tblEncryptTest](
[EncryptID] [int] IDENTITY(1,1) NOT NULL,
[TextValue] [varchar](50) NOT NULL,
[TextEncValue] [varbinary](8000) NULL,
[DateValue] [date] NOT NULL,
[DateEncValue] [varbinary](8000) NULL,
CONSTRAINT [PK_tblEncryptTest] PRIMARY KEY CLUSTERED
(
[EncryptID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
原始值的示例为 TextValue = 'This is a text Value', DateValue = '12/15/1986'
谢谢你
BACKUP CERTIFICATE TestCert
仅备份证书,而不备份其保护的任何内容。
然后我删除了对称密钥
密钥现已丢失,您无法恢复它,您也无法恢复您加密的任何数据。扔掉一切,重新开始。
CREATE SYMMETRIC KEY TestSymKey
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE TestCert;
这只是创建一个new密钥,由现在恢复的旧证书保护。证书和密钥无关,只是密钥现在由证书加密和保护。
您需要备份key。
BACKUP SYMMETRIC KEY TestSymKey
TO FILE = N'c:\Backup\TestCert.cer'
ENCRYPTION BY PASSWORD = N'AReallyStr0ngK#y4You';
然后恢复它
RESTORE SYMMETRIC KEY TestSymKey
FROM FILE = N'c:\Backup\TestCert.cer'
DECRYPTION BY PASSWORD = N'AReallyStr0ngK#y4You';
请注意,遗憾的是您无法使用证书保护密钥备份。相反,必须使用密码,该密码使用 3DES(一种弱加密)进行加密。
另一种方法是使用相同的参数重新创建对称密钥。为此,您需要了解来源。所以将原来的
CREATE
更改为:
CREATE SYMMETRIC KEY TestSymKey
WITH
ALGORITHM = AES_256,
KEY_SOURCE = 'ReallyStrongPasswordHere',
IDENTITY_VALUE = 'id_phrase'
ENCRYPTION BY CERTIFICATE TestCert;
现在要重新创建它,只需在新服务器上执行相同的语句即可。它必须是相同版本的 SQL Server。
最后一点:如果您备份/恢复数据库本身,那么证书和密钥也会被备份。