Question

I am facing issue while decryption, Please help me if my column encryption/decryption process is wrong.

I encrypted table in Source DB and back up certificate, then exported my encrypted table result to CSV from source DB.

In the destination DB, I Created master Key, and using certificate backup (of my source DB) I created certificate in destination and then my symmetric key.

Now I imported the CSV result into my destination DB table and running my decryption script. But it gives me NULL value. (Decryption works fine in source DB, same is not working in destination).

Below is my sample script,

    ----AT MY SOURCE DB---- 
CREATE TABLE tbluser 
  ( 
     id          INT, 
     NAME        VARCHAR(200), 
     encryptname VARBINARY(200) 
  ) 

INSERT INTO tbluser 
            (id, 
             NAME) 
VALUES      (1, 
             'Raj'), 
            (2, 
             'Vimal') 

CREATE master KEY encryption BY password = 'M@sterKey123' 

CREATE certificate testcert1 WITH subject = 'Test my Certificate'; 

BACKUP certificate testcert1 TO FILE = 'D:\DESKTOP\Certificate\TestCert1.cer' 
WITH private KEY ( FILE = 'D:\DESKTOP\Certificate\pkTestCert1.pvk', encryption 
BY password = 'Certific@te123' ); 

CREATE symmetric KEY symkeytest1 WITH algorithm = aes_256 encryption BY 
certificate testcert1; 

OPEN symmetric KEY symkeytest1 decryption BY certificate testcert1; 

UPDATE tbluser 
SET    encryptname = Encryptbykey(Key_guid('SymKeyTest1'), NAME); 

CLOSE symmetric KEY symkeytest1; 

OPEN symmetric KEY symkeytest1 decryption BY certificate testcert1; 

SELECT TOP 5 NAME, 
             CONVERT(VARCHAR(50), Decryptbykey(encryptname)) DecryptedName 
FROM   tbluser; 

CLOSE symmetric KEY symkeytest1 

DECLARE @str       NVARCHAR(2000), 
        @path      NVARCHAR(200)='D:\DESKTOP\Certificate', 
        @TableName NVARCHAR(100)='tbluser' 

SET @str = 'BCP Test.dbo.' + @TableName + ' OUT ' + @path + '\' 
           + @TableName 
           + '.csv  -c -t^| -T -S MAILPTP45\SQL2012' 

EXEC Xp_cmdshell 
  @str 

----AT MY DESTINATION DB---- 
CREATE master KEY encryption BY password = 'M@sterKey123' 

CREATE certificate testcert1 FROM FILE = 'D:\DESKTOP\Certificate\TestCert1.cer' 
WITH private KEY(FILE = 'D:\DESKTOP\Certificate\pkTestCert1.pvk', decryption BY 
password = 'Certific@te123') 

CREATE symmetric KEY symkeytest1 WITH algorithm = aes_256 encryption BY 
certificate testcert1; 

CREATE TABLE tbluser 
  ( 
     id          INT, 
     NAME        VARCHAR(200), 
     encryptname VARBINARY(200) 
  ) 

BULK INSERT [tbluser] 
  FROM 'D:\DESKTOP\Test\tbluser.csv' 
  WITH 
    ( 
      fieldterminator = '|', 
      rowterminator = '\n' 
    ) 
OPEN symmetric KEY symkeytest1 decryption BY certificate testcert1; 

SELECT TOP 5 NAME, 
             CONVERT(VARCHAR(50), Decryptbykey(encryptname)) DecryptedName 
FROM   tbluser; 

CLOSE symmetric KEY symkeytest1 
Was it helpful?

Solution

I think the solution to your problem can be found in this post (highlighting mine):

How to Create Two Identical Symmetric Keys

To summarize:

SQL Server offers a sophisticated encryption key management system allowing for multiple levels of symmetric and asymmetric keys that protect each other. (See: The SQL Server Encryption Hierarchy) However, there is one use case that is only marginally supported by SQL Server: Creating the same symmetric key in two databases or even on two separate servers.

There are only two methods to achieve this. The first is the use of an External Key Management solution in the form of an EKM module. However, EKM modules are often rather pricey investments and therefore not for everyone. The second method, and the only one not requiring external components, is a special form of the CREATE SYMMETRIC KEY statement. It allows us to specify a key source and an identity value. If identical values are used for these parameters, the resulting keys will be identical too.

CREATE SYMMETRIC KEY WITH KEYSOURCE Example

The extended syntax of the CREATE SYMMETRIC KEY statement is fairly straight forward, you just need to add the KEY_SOURCE and IDENTITY_VALUE clauses right after specifying the algorithm:

CREATE SYMMETRIC KEY SymmetricKey1
  WITH ALGORITHM = AES_256,
       KEY_SOURCE = '********************',
       IDENTITY_VALUE = 'SymmetricKey1'
  ENCRYPTION BY CERTIFICATE KeyProtection;

The key source is used to generate the actual key bits. It is using some form of key expansion algorithm. However, and that is my biggest concern with this method, which algorithm is used is not published. That means, while we can select the AES 256 algorithm for the key, if we actually get AES 256 level protection is unclear.

To clarify, the encryption algorithm used for an AES 256 key is always AES 256. However, if the key can be guessed easier than a random 256-bit key, you are dealing with a weakness. As we do not know how the key is derived, we also do not know how secure it is. The Identity Value

The string that is specified in the IDENTITY_VALUE clause is not used for the generation of the actual key. It is only used to generate the key GUID that helps SQL Server identify the key necessary for decryption of an encrypted value. The DECRYPTBYKEY function does not allow us to specify the symmetric key to use for the decryption. Instead, SQL Server stores the GUID of the key that was used to encrypt the value as part of that value. That way, SQL Server will always know which key to use.

When looking at the documentation, you can get the impression, that the IDENTITY_VALUE needs to be kept a secret. However, it being unknown does not in any way increase security. If the KEY_SOURCE is known but the identity value isn't, we can just create a new key with a new GUID and then replace the key GUID within the encrypted value. As that value is just prepended to the actual cipher text, this is a simple string substitution operation.

Summary

The CREATE SYMMETRIC KEY statement allows us to specify a string as a KEY_SOURCE. That value is used to generate the actual key bits in a repeatable way. Therefore, we can use this feature to create the same key in different location.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top