Chr*_*s L 5 sql-server encryption
我们有一个(SQL 代理)作业,它每晚备份我们的生产数据库(并恢复到测试数据库服务器),并且我们正在为表中的某些列添加加密。我创建了一个主密钥并将其绑定到服务主密钥:
Create MASTER KEY Encryption By Password = 'MyReallyStrongPW'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY CLOSE MASTER KEY
Run Code Online (Sandbox Code Playgroud)
我还创建了我的证书:
CREATE CERTIFICATE [My_Cert] With Subject = 'My Certificate'
CREATE SYMMETRIC KEY My_Symm_Key WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE [MY_Cert];
Run Code Online (Sandbox Code Playgroud)
同一个账号
域\MyBigSqlAccount
正在运行 sql (prod & test) 的两个实例。
能够看到数据(在测试中)的唯一方法是运行这个:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'MyReallyStringPW'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY CLOSE MASTER KEY
Run Code Online (Sandbox Code Playgroud)
然后这将起作用:
OPEN SYMMETRIC KEY My_Symm_Key DECRYPTION BY CERTIFICATE [My_Cert]
Select Convert(varchar, DecryptByKey(EncryptedColumn)) as DecryptedCol From SomeTable
Run Code Online (Sandbox Code Playgroud)
我能够让它工作的唯一方法是将密码放入纯文本作为 sql 作业中的一个步骤
步骤1:恢复数据库,步骤2:使用密码将Master Key绑定到测试服务器上的Service Master Key。
以纯文本形式存储密码(或解密包含密码的文件的密码)似乎不太明智。
两者都使用 Sql Server 2012。
相关(Q1b)SQL Server 2008 加密的简单实现
问题是我如何绕过以纯文本形式存储我的密码,并且仍然对 prod 和文本使用加密?
毫无疑问,第 2 步需要新的设计。我建议,第 2 步将使用随机备份数据库主密钥来备份数据库主密钥,而不是传递数据库主密钥密码(该密码通常保持相当恒定并且不会经常更改)。生成足够长度的密码。然后可以在源处对密码进行加密,加密后传递到目标服务器,然后解密并用于恢复数据库主密钥。对于此设计,您需要将过程、证书和视图添加到源服务器 msdb 数据库,并将过程和证书添加到目标服务器 msdb 数据库。您还需要在目标服务器上创建一个共享文件夹,并向产品服务器的 SQL 代理服务帐户授予写入权限。涉及的对象有:
第 2 步包括调用 prod 服务器过程,然后调用 TargetServer 过程以完成恢复。您可以使用链接服务器、osql 调用或其他方法来调用目标服务器上的过程。
为了进一步提高安全性,您可以在备份后将私钥删除到生产服务器上。这样只有目标服务器才能解密密码。密码每天也会不同且不可预测。另一个好处是 DMK 每次都会被删除,并且仅在步骤 2 的持续时间内存在于共享上,这应该是几秒钟的事情。
这可以成功完成,但是,我还想问是否应该这样做。如果这些数据非常敏感以至于需要加密,那么它是否应该在您的生产系统之外可用?如果您决定不这样做,那么您可以将证书和对称密钥删除到目标数据库中,并创建具有相同名称的新证书和对称密钥以避免异常。任何使用这些的调用都将返回 null。我已包含以下视图:
/*
generates a random 128 character string from all
valid password characters except single quote
*/
CREATE VIEW dbo.vwGetRandomPass
AS
WITH s1
AS (
SELECT TOP 32 CHAR(number) AS chr
FROM master..spt_values
WHERE number BETWEEN 48
AND 57 -- number characters
ORDER BY newid()
)
,s2
AS (
SELECT TOP 32 CHAR(number) AS chr
FROM master..spt_values
WHERE number BETWEEN 65
AND 90 -- Upper letters
ORDER BY newid()
)
,s3
AS (
SELECT TOP 32 CHAR(number) AS chr
FROM master..spt_values
WHERE number BETWEEN 97
AND 122 -- Lower letters
ORDER BY newid()
)
,s4
AS (
SELECT TOP 32 CHAR(number) AS chr
FROM master..spt_values
WHERE number BETWEEN 33
AND 38
OR number BETWEEN 40
AND 47 -- sign characters
OR number BETWEEN 58
AND 64
OR number BETWEEN 91
AND 96
OR number BETWEEN 123
AND 126
ORDER BY newid()
)
,final
AS (
SELECT chr
FROM s1
UNION ALL
SELECT chr
FROM s2
UNION ALL
SELECT chr
FROM s3
UNION ALL
SELECT chr
FROM s4
)
SELECT pass = (
SELECT chr AS [text()]
FROM final
ORDER BY newid()
FOR XML path('')
)
GO
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
751 次 |
| 最近记录: |