【问题标题】:What is the impact of the `PersistKeySet`-StorageFlag when importing a Certificate in C#在 C# 中导入证书时,`PersistKeySet`-StorageFlag 有什么影响
【发布时间】:2016-08-20 10:02:27
【问题描述】:

在我的应用程序中,使用以下代码以编程方式将客户端身份验证证书添加到 MY-Store:

//certData is a byte[]
//password is a SecureString
X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable);
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
}
finally
{
    store.Close();
}

使用此代码,证书已正确导入我测试的所有机器上的MY-Store(指纹和证书链也正确)。

但在某些机器上(Windows 7 Professional SP1 和 Widnows Server 2008 R2 与本地用户帐户)之后,证书无法用于客户端身份验证(“无法为 SSL/TLS 安全通道建立信任关系")。 在具有域用户帐户的 Windows 8.1 Enterprise 计算机上,身份验证有时但并非总是有效。

我拼命尝试了几件事,最后找到了将X509KeyStorageFlags.PersistKeySet 添加到存储标志的解决方案。 所以第一行现在是:

X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

使用这些标志,证书可以在所有设备上使用。 尽管我很高兴我的应用程序现在可以按预期方式运行,但我想了解为什么? PersistKeySet-Flag 究竟做了什么?为什么它会影响证书的使用时间和使用对象?

MSDN 在这种情况下不是很有帮助。

【问题讨论】:

标签: c# ssl client-certificates


【解决方案1】:

在导入 PFX 时,公共证书元素被加载到内存中,而私钥材料被存储在密钥存储提供程序中。 .NET 中的默认行为是在释放 X509Certificate2 对象(或其资源正在通过垃圾收集完成)时删除私钥材料。 PersistKeySet 标志防止这种清理发生。

如果您要添加到持久证书存储区,您总是希望设置PersistKeySet。不添加到持久存储时,您很可能不希望设置它。

如果您的导入过程是长期存在的,那么您会看到的行为是在导入后的任意时间对私钥的新访问开始失败。如果它是短暂的,那么它可能总是无法工作。

【讨论】:

【解决方案2】:

据我了解,PersistKeySet 标志(如果指定)会将导入的 PFX 的私钥保存在磁盘上,与导出 PFX(用户密钥集或机器密钥集)的来源证书相同的位置。如果 PFX 是由工具生成的(例如 pvk2pfx.exe),则没有源并使用默认值(userkeyset)。

在这种情况下,如果作为导出 PFX 来源的证书的私钥存储在 machinekeyset 中,则私钥将在 machinekeyset 中导入,此处为:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

否则,它将存储在 userkeyset 中,这里: \Users\user\AppData\Roaming\Microsoft\Crypto\RSA\S-1-....

如果您希望您的证书在整个机器上可用,而不考虑 PFX 的原始位置,您可能需要考虑使用 MachineKeySet

【讨论】:

  • 你知道证书上的哪个属性表明它是从哪里导出的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多