我正在使用 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 列用于存储原始值(测试目的),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
仅备份证书,而不备份其保护的任何内容。密钥现在已丢失,您无法恢复它,也无法恢复您加密的任何数据。将其全部丢弃并重新开始。
这只是创建一个新密钥,受现在恢复的旧证书保护。证书和密钥无关,只是密钥现在由证书加密和保护。
您需要的是备份密钥。
然后恢复它
请注意,遗憾的是您无法使用证书保护密钥备份。相反,必须使用密码,该密码使用 3DES(一种弱加密)进行加密。
另一种方法是使用相同的参数重新创建对称密钥。为此,您需要知道来源。因此,将原始密钥更改
CREATE
为:现在要重新创建它,只需在新服务器上执行相同的语句。它必须是相同版本的 SQL Server。
最后要注意的是:如果您备份/恢复数据库本身,那么证书和密钥也将被备份。