【问题标题】:Symmetric Encryption By Key Behavior通过密钥行为进行对称加密
【发布时间】:2016-03-04 12:34:38
【问题描述】:

我刚刚运行了以下测试,我很困惑:

我创建了一个这样的表:

CREATE TABLE [dbo].[enxtest](
    [id] [int] NOT NULL,
    [cleara] [varchar](50) NULL,
    [encrypta] [varbinary](2000) NULL,
    [clearb] [varchar](50) NULL,
 CONSTRAINT [PK_enxtest] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

我已经用这样的数据填充了它:

id | cleara        | encrypta | clearb
1  | teststring!1  | NULL     | NULL
2  | teststring!1  | NULL     | NULL
3  | teststring!2  | NULL     | NULL
4  | teststring!2  | NULL     | NULL

我运行了一个脚本来加密 cleara 的内容,一次使用一个 SQL Server 对称密钥和证书对,就像这样(仅相关代码,sproc 内部),并将加密值插入到 encrypta 字段中:

OPEN SYMMETRIC KEY THIS_IS_THE_KEY
    DECRYPTION BY CERTIFICATE THIS_IS_THE_CERT
CONVERT(varbinary(2000), EncryptByKey(Key_GUID('THIS_IS_THE_KEY'), cleara), 1)

然后我们删除了数据库主密钥、对称密钥和证书并重新创建了它们,并赋予它们以前相同的名称。我运行了一个脚本来解密 varbinary,类似于上面的加密代码并将其插入到 clearb 中。

这个查询给了我以下结果:

SELECT id, cleara, clearb
FROM enxtest;

id | cleara        | encrypta | clearb
1  | teststring!1  | NULL     | teststring!1
2  | teststring!1  | NULL     | teststring!1
3  | teststring!2  | NULL     | teststring!2
4  | teststring!2  | NULL     | teststring!2

问题:

  1. 这怎么可能?我期待得到 clearb == clearb 但是 清除!=清除。我希望把钥匙换掉会产生 始终不正确的 varchar 值。
  2. 有没有办法将备份恢复到另一台服务器,同时保持表中的二进制数据不受影响,创建新的密钥,将数据可靠地解密为一致但不正确的(与原始明文值相比)值?

编辑:这是我们分批运行的完整脚本。

--Batch 1
declare @e1 varbinary(2000);
declare @c1 varchar(50);
select @c1 = cleara from enxtest where id = 1;
exec dbo.spEncryptString @cleartextString = @c1, @encryptedString = @e1 OUTPUT;

declare @e2 varbinary(2000);
declare @c2 varchar(50);
select @c2 = cleara from enxtest where id = 2;
exec dbo.spEncryptString @cleartextString = @c2, @encryptedString = @e2 OUTPUT;

declare @e3 varbinary(2000);
declare @c3 varchar(50);
select @c3 = cleara from enxtest where id = 3;
exec dbo.spEncryptString @cleartextString = @c3, @encryptedString = @e3 OUTPUT;

declare @e4 varbinary(2000);
declare @c4 varchar(50);
select @c4 = cleara from enxtest where id = 4;
exec dbo.spEncryptString @cleartextString = @c4, @encryptedString = @e4 OUTPUT;

update enxtest
set encrypta = @e1
where id = 1;

update enxtest
set encrypta = @e2
where id = 2;

update enxtest
set encrypta = @e3
where id = 3;

update enxtest
set encrypta = @e4
where id = 4;


/*
--Batch 2
drop symmetric key THIS_IS_THE_KEY;
drop certificate THIS_IS_THE_CERT;
drop master key;

create master key encryption by password = 'somepassword';
create certificate THIS_IS_THE_CERT with subject = 'subject' expiry_date = '20161231';
create symmetric key THIS_IS_THE_KEY with algorithm = AES_256
    key_source = 'source' identity_value = 'identity' encryption by certificate THIS_IS_THE_CERT;
*/

--Batch 3
declare @e1 varbinary(2000);
declare @c1 varchar(50);
select @e1 = encrypta from enxtest where id = 1;
exec dbo.spDecryptString @encryptedString = @e1, @cleartextString = @c1 OUTPUT;

declare @e2 varbinary(2000);
declare @c2 varchar(50);
select @e2 = encrypta from enxtest where id = 2;
exec dbo.spDecryptString @encryptedString = @e2, @cleartextString = @c2 OUTPUT;

declare @e3 varbinary(2000);
declare @c3 varchar(50);
select @e3 = encrypta from enxtest where id = 3;
exec dbo.spDecryptString @encryptedString = @e3, @cleartextString = @c3 OUTPUT;

declare @e4 varbinary(2000);
declare @c4 varchar(50);
select @e4 = encrypta from enxtest where id = 4;
exec dbo.spDecryptString @encryptedString = @e4, @cleartextString = @c4 OUTPUT;

update enxtest
set clearb = @c1
where id = 1;

update enxtest
set clearb = @c2
where id = 2;

update enxtest
set clearb = @c3
where id = 3;

update enxtest
set clearb = @c4
where id = 4;

--Check
select * from enxtest;

【问题讨论】:

  • 这看起来很奇怪。你有完整的复制脚本吗?
  • 我愿意,我会在早上发布编辑。
  • @BenThul 我已经添加了我们运行的完整脚本,分批进行。
  • 出于好奇,您实际上想做什么?如果要恢复/解密数据,通常不会删除和重新创建密钥。如果你想要一个单向函数,我建议使用哈希! :)
  • @BenThul 当我们将生产恢复到我们的开发/测试环境时,试图找到一个易于模糊测试的敏感数据。我只想交换密钥,而不是生成新的垃圾数据进行测试,然后用新密钥加密。我想密文中有标头数据,它指定使用了哪个密钥,只有那个密钥才能解密它。无论如何我昨天放弃并写了一个模糊器,谢谢你的帮助。

标签: sql-server encryption sql-server-2012


【解决方案1】:

您没有完全生成重现脚本(例如,我没有您的存储过程的主体),但我看到了问题。当您创建具有相同 KEY_SOURCE 参数的对称密钥时,您实际上是在创建完全相同的密钥。一旦知道这一点,修复就很容易了 - 每次创建密钥时为 KEY_SOURCE 提供不同的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-09
    • 2010-10-30
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    相关资源
    最近更新 更多