銀行口座の詳細を含む従業員情報を格納するデータベースを構築しています。銀行口座の詳細は、当社を使用している現在または過去のスタッフを確認できるように保存されます。MSDNやその他の場所で SQL Server 2008 R2 Encrption and Decryption を読んでいて、次のサンプル スクリプトを思いつきました。
IF NOT EXISTS(SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'BankDetai!5'
GO
CREATE CERTIFICATE Employees_01 WITH SUBJECT = 'Employee Bank Account Details'
GO
CREATE SYMMETRIC KEY AccountNos_01
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE Employees_01
GO
CREATE TABLE #Bank_Accounts
( Id INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_BankAccount_Id PRIMARY KEY CLUSTERED (Id ASC)
,AccountNumber VARBINARY(128) NOT NULL
,BankName NVARCHAR(255) NOT NULL
,CountryCode VARCHAR(2) NOT NULL
,CreateDate DATETIME2(0) NOT NULL
,EmployeeId INT NOT NULL
,IsActive BIT NOT NULL
,SortCode VARBINARY(128) NOT NULL
);
OPEN SYMMETRIC KEY AccountNos_01
DECRYPTION BY CERTIFICATE Employees_01;
CREATE TABLE #SampleBankAccounts
( Id INT IDENTITY(1,1)
,AccountNumber VARCHAR(255)
,BankName NVARCHAR(255)
,CountryCode VARCHAR(2)
,EmployeeId INT NOT NULL
,IsActive BIT
,SortCode VARCHAR(255))
INSERT #SampleBankAccounts
SELECT * FROM
( SELECT
'123456789' AccountNo
,'Barclays' BankName
,'US' Country
,1 Employee
,1 IsActive
,'12-34-56' SortCode
UNION
SELECT
'9876543210'
,'Barclays'
,'US'
,1
,0
,'12-34-56'
UNION
SELECT
'111111111111'
,'HSBC'
,'UK'
,2
,1
,'222222'
UNION
SELECT
'IBAN 123 456 9875 3215'
,'Nationwide'
,'ES'
,3
,1
,'00_gn321654'
)AS Samples
ORDER BY Employee
MERGE #Bank_Accounts AS Target
USING #SampleBankAccounts AS Source ON Target.EmployeeId = Source.EmployeeId
AND Source.AccountNumber = Target.AccountNumber
AND Source.BankName = Target.BankName
AND Source.CountryCode = Target.CountryCode
AND Source.SortCode = Target.SortCode
WHEN NOT MATCHED
THEN INSERT (AccountNumber, BankName,CountryCode,CreateDate,EmployeeId,IsActive,SortCode)
VALUES (
ENCRYPTBYKEY(KEY_GUID('AccountNos_01'),Source.AccountNumber)
,Source.BankName
,Source.CountryCode
,GETDATE()
,Source.EmployeeId
,Source.IsActive
,ENCRYPTBYKEY(KEY_GUID('AccountNos_01'),Source.SortCode));
GO
DROP TABLE #SampleBankAccounts
これで問題ないようですが、変数を取得して、@AccountNo
保存した銀行口座のいずれかと一致するかどうかを確認する必要があります (おそらくストアド プロシージャを使用します)。可能であれば、スクリプトでの復号化は避けたいので、@AccountNo
変数を暗号化してから比較することが可能かどうか疑問に思ったので、一致する可能性があります。
DECLARE @MyTestBankAccount NVARCHAR(255) = '123456789'
DECLARE @MyEncryptedTestBankAccount VARBINARY(128)
OPEN SYMMETRIC KEY AccountNos_01
DECRYPTION BY CERTIFICATE Employees_01;
SELECT @MyEncryptedTestBankAccount = ENCRYPTBYKEY(KEY_GUID('AccountNos_01'),@MyTestBankAccount)
SELECT
AccountNumber
,EmployeeId
FROM Bank_Accounts
WHERE
@MyEncryptedTestBankAccount = AccountNumber
これは動作しません; ご覧のとおり、テーブルに存在するはずの口座番号を使用していますが、結果が返されません。口座番号列を復号化して変数と比較しようとしましたが、大量の漢字が出てきて(この質問のように)、変数を暗号化および復号化して作成された文字と一致しないため、それも試合には向かない…
では、次のクエリ (上記のデータを使用) で、アカウントの詳細の暗号化および復号化された値が得られないのはなぜでしょうか? この方法を使用して、特定の銀行口座に対して従業員の銀行口座を検索できますか?
OPEN SYMMETRIC KEY AccountNos_01
DECRYPTION BY CERTIFICATE Employees_01;
SELECT
AccountNumber AS Encrypted_AccountNo
,EmployeeId AS EmployeeId
,CONVERT(NVARCHAR,DECRYPTBYKEY(AccountNumber)) AS Decrypted_AccountNo
FROM Bank_Accounts