I am working in a test environment with SQL Server 2017 to verify that encrypting data with a symmetrical key will meet our needs. I have successfully encrypted and decrypted data using the symmetrical key below, but when I test the restore of the key on the same server, it will not decrypt the data that was originally encrypted. I am sure I am just missing a piece of the puzzle but I cannot see what it is.
I created the certificate and key with the following:
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;
I then backed up the certificate using the following:
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'
)
;
I then deleted the symmetrical key and then the certificate. I successfully recreated the certificate and key using the following:
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;
I am able to use the same select statement (no errors) but the decrypted data comes back NULL. If I update the encrypted data in the table with the new key, the select statement pulls the decrypted data successfully.
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
The table is setup with 4 columns. 2 to store the orignal value (test purposes) and two to store the encryted values.
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]
An example of the original values is TextValue = 'This is a text Value', DateValue = '12/15/1986'
Thank you
BACKUP SYMMETRIC KEYandRESTOREthat also (or backup the whole database). What protects the symmetric key (the certificate) is irrelevant if you create a new one.