设置 Always-Encrypted 功能时,Set-SqlColumnEncryption 无法从 MS 证书存储中找到或检索主列密钥

Set-SqlColumnEncryption cannot find or retrieve master column key from ms certificate store when setting up Always-Encrypted feature

我正在尝试在 MS SQL Server 2016 数据库的几列上实施始终加密功能。事实上,我已经在我的 UAT 数据库上成功地实现了它。但是,当尝试在我的生产数据库上执行相同的步骤时,出现以下错误:

Set-SqlColumnEncryption:无法使用密钥库提供程序解密列加密密钥:'MSSQL_CERTIFICATE_STORE'。加密列加密密钥的最后 10 个字节是:'xx-xx-xx-xx-xx-xx-xx-xx-xx-xx'。 键集不存在

一些细节:我正在执行命令

Set-SqlColumnEncryption -ColumnEncryptionSettings $l_columnEncryptionSettings -InputObject $l_database

在 powershell 中。主列密钥在 ms sql 帐户 运行 进程的用户存储中。它可以在 "Certificates - Current User\Personal\Certificates" 中的 certmgr 中看到,它包含 public 和私钥(显示证书信息显示 "you have a private key that corresponds to this certificate")。

查看数据库中的 Always-Encrypted Keys 条目,Column Master Key 显示密钥路径为 CurrentUser/my/<fingerprint>,其中 <fingerprint> 确实与证书的指纹匹配在 MSSQL_CERTIFICATE_STORE.

我看过这个问题(),但是那里的"solution"要么不适用(我已经将public和私钥导入商店),要么不清楚(它提到 "access" 到一个目录,但没有提供详细的访问权限类型,我正在处理的帐户确实对提到的目录具有读取权限。)

最奇怪的是,我已经在同一台机器上成功实现了UAT DB(不同的DB,相同的SQL实例,不同的用户),但我看不出两者之间有什么区别设置。

有谁知道可能导致此错误的原因或如何更正它?谢谢。

编辑:当我提出这个问题时,问题似乎是功能设置不正确,所以这个问题是合理的。经过进一步调查(见下文),结果证明是数据损坏,所以除了我自己可能没有人能回答这个问题。

CertMgr 显示本地存储中的证书已使用私钥导入:打开证书清楚地显示 "You have a private key that corresponds to this certificate",证书是从包含私钥的 .pfx 文件导入的。但是,我从 Misrosoft 下载、编译并 运行 "findprivatekey.exe" 工具。我运行

findprivatekey My currentUser -t "xx xx ... xx"

奇怪的是它返回

FindPrivateKey 失败,原因如下: 无法获取私钥文件名

事实上,无论我如何尝试指定证书(指纹、CN 等),它总是以同样的失败返回。我删除了证书并重新 运行 我的导入脚本。同样的剧本,不同的日子。然后一切正常。

我只能得出结论,包含私钥文件的目录不知何故已损坏。

附录:

对于其他有类似问题的人,损坏原因的详细信息及其修复:第二天,私有证书数据再次消失。一位技术人员敏锐的眼睛注意到私钥的文件路径(如 findprivatekey 命令所示,在重新安装证书后立即显示)位于 "Roaming" 配置文件子树中,尽管该帐户是为本地配置文件配置的。一些调查揭示了一个名为 "Credential Roaming" 的 Windows 特征。仔细阅读此文档:https://social.technet.microsoft.com/wiki/contents/articles/11483.credential-roaming.aspx,末尾是 "Certificates Become Unusable or Renewed" 部分,在本例中适用。发出命令 certutil -user -repairstore My "{Serialnumer}" 解决了问题。