SQL Server:BACKUP MASTER KEY每次产生不同的输出

时间:2016-11-16 22:21:02

标签: sql-server tsql

我在新的数据库上运行了这个:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '27c381e5-27cf-483f-81bf-143845911a5f';

BACKUP MASTER KEY TO FILE = 'c:\temp\key1.key'
ENCRYPTION BY PASSWORD = '27c381e5-27cf-483f-81bf-143845911a5f'

BACKUP MASTER KEY TO FILE = 'c:\temp\key2.key'
ENCRYPTION BY PASSWORD = '27c381e5-27cf-483f-81bf-143845911a5f'

但是,备份不同:

C:\Windows\system32>type c:\temp\key1.key | md5sum
702f95c38ea9b740ebaa7e186b9c12ec *-

C:\Windows\system32>type c:\temp\key2.key | md5sum
31906913d9d7c15fc1ba90a9635fee52 *-

我也进行了十六进制转储,文件远非类似。

有人可以解释这种行为吗?我试图进行备份和恢复,但我似乎无法弄清楚这个过程应该如何工作。恢复失败,看起来我甚至无法弄清楚备份的进展情况。

1 个答案:

答案 0 :(得分:1)

TL; DR:

密码文本在每次加密时都是不同的,所有其他条件都相同。我相信这是故意的"随机化"输出的目的是为了不让密码猜测更容易。 (但签名将始终相同。)

如果您要查看您的DMK备份文件'并排的内容,你会看到前40-60个字节的结构几乎相同(例如,相同位置的空格量相同);只有一些数据不同。这是盐,其中包括盐的位置。盐不需要隐藏;它只需要是随机的。

现在关于您在恢复期间收到的错误,由于某种原因,这些错误无法通知。我已经像您一样创建了测试环境和两个DMK备份。另外,为了使事情更加真实,我创建了一个证书而没有指定加密密码:

create certificate [TestCert] authorization [dbo]
    with subject = 'DMK Restore Test certificate';

这意味着证书私钥将使用DMK加密,因此现在我们有一些加密数据。如果我尝试从第一次备份恢复DMK:

restore master key from file = 'D:\Tests\Key1.dmk'
    decryption by password = 'asdfdgkjh98hvio'
    encryption by password = 'nmbneknfownoih';

SSMS输出以下消息(不是错误,请注意):

  

旧的和新的主密钥是相同的。无需重新加密数据。

密钥当前处于打开状态,因为它是默认行为,并且未检测到任何差异。尝试使用我们的证书创建签名证明可​​以访问由DMK(证书的私钥)加密的数据:

select signbycert(cert_id('TestCert'), 'ASDfgh');

(您将看到上面的一些varbinary(128)输出)。 但是,如果我通过从master删除其副本来关闭密钥自动打开,这是恢复数据库备份时的常见情况:

alter master key drop encryption by service master key;

然后尝试使用与上面相同的restore master key语句进行恢复,确实会出错:

  

Msg 15329,Level 16,State 30,Line 1

     

当前的主密钥无法解密。如果这是一个数据库   主密钥,您应该尝试在之前的会话中打开它   执行此操作。 FORCE选项可用于忽略此选项   错误并继续操作但旧数据加密的数据   主密钥将丢失。

密钥(现有密钥和正在恢复的密钥)仍然相同,但这次SQL Server无法看到它 - DMK已关闭。出于同样的原因,尝试使用证书签名返回NULL。请注意提及FORCE选项。如果我添加它:

restore master key from file = 'D:\Tests\Key1.dmk'
    decryption by password = 'asdfdgkjh98hvio'
    encryption by password = 'nmbneknfownoih'
    force;

结果再次只是一条信息性消息:

  

当前的主密钥无法解密。错误被忽略了   因为指定了FORCE选项。

获取数据的唯一方法是明确打开DMK,或重新启用自动打开:

open master key decryption by password = 'nmbneknfownoih';
go
-- And if you need it to be always available in the future
alter master key add encryption by service master key;
go

之后,证书签名再次开始工作(并且将返回与第一次完全相同的二进制数据)。