我重新启动时为什么会丢失密钥容器?

时间:2015-09-23 17:03:13

标签: visual-studio cryptography cryptoapi

多年来,我们一直将我们的强名称保存在一个密钥容器中。 Visual Studio并不直接支持,但如果您只是编辑.csproj文件并添加:

,它可以正常工作
<KeyContainerName>MyKeyName</KeyContainerName>

我们通过执行以下操作将密钥安装到密钥存储区中:

sn -m Y
sn -i MyKeyFile.snk MyKeyName

然后我们可以从该机器中删除MyKeyFile.snk,并且密钥更安全。

最近,重启后这已经成为一个问题。我们怀疑这个问题是由VS 2015引入的,但它可能是由Windows 8和/或10引起的。我们将密钥安装到密钥容器中,一切正常。然后,我们重新启动该计算机并构建失败:

CSC : error CS7028: Error signing output with public key from container 'MyKeyName' -- Keyset does not exist (Exception from HRESULT: 0x80090016)

看起来密钥容器在重新启动时丢失了,但是,如果我们这样做:

sn -m Y
sn -i MyKeyFile.snk MyKeyName

失败了:

Failed to install key pair -- Object already exists.

我们必须使用sn -d删除密钥容器,然后将其添加回来,Visual Studio很高兴。

这里发生了什么?为什么Visual Studio可以在重启后看到我们的密钥容器,而sn可以看到它?密钥容器实际存放在哪里?

1 个答案:

答案 0 :(得分:3)

首先,使用&#34; sn -m&#34;时需要小心。命令在基于机器的键和基于用户的键之间切换。该命令区分大小写,并且处理无效值,就像未指定值一样,将显示当前设置。所以,&#34; sn -m Y&#34;不启用基于机器的密钥,你必须说&#34; sn -m y&#34; (小写y或n)。

当前版本的CSC.exe似乎只使用基于机器的密钥。我不知道这是否是最近的更改,但这是我在使用.NET V4.6和VS 2015时观察到的行为。

计算机密钥保存在C:\ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys中。当你执行&#34; sn -i file.snk name&#34;要安装密钥,将在该目录中创建一个文件。该文件以几个GUID命名,因此您必须查看修改日期以确定哪一个刚刚创建。

如果您检查新文件的属性并查看&#34;安全&#34;选项卡,您将看到&#34; LogonSessionId_n_nnn&#34;条目。 ACL中的该条目授予您的登录会话访问权限,但是,如果重新启动,则会获得不同的登录会话,以便该条目不再授予您访问权限。这就是为什么我们可以安装强名称密钥并使用它们直到我们重新启动。它还解释了为什么在重新安装之前需要删除密钥,密钥仍然存在但是,我们无法访问它。

您可以编辑该文件的ACL并自行授予&#34; Read,Read&amp;执行&#34;使用AD用户名或组进行访问,强名称密钥即使在重新启动后也能正常工作。