在 .NET 5 中设置证书私钥权限

Posted

技术标签:

【中文标题】在 .NET 5 中设置证书私钥权限【英文标题】:Set Certificate PrivateKey Permissions in .NET 5 【发布时间】:2021-03-09 08:22:23 【问题描述】:

我有一个需要为证书私钥设置权限的要求,我使用了以下方法 (SetCertificatePrivateKeyPermissions),该方法在 .Net framework 4.7.2上运行良好> 但是现在我不得不将项目框架迁移到 .Net 5,由于这个项目框架升级,这个现有的代码被破坏了。

RSACryptoServiceProvider 和 CspParameters 类是指 System.Security.Cryptography.Csp.dll (C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.Security .Cryptography.Csp.dll),通过这个 dll 参考,我面临现有代码的 2 个问题

    在将 certificate.PrivateKey 转换为 RSACryptoServiceProvider 期间,它返回 NULL。

    在创建 CspParameters 的实例时,我无法从 rsa 分配 CryptoKeySecurity 值,因为 .NET 5 的 RSACryptoServiceProvider 和 CspParameters 类都不可用/支持此属性,而 .NET 4.7.2 版本支持它。

请告诉我如何处理这个问题?或者是否有任何替代解决方案可以让我在 .NET 5 中设置证书私钥的权限?

代码sn-p:

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

public static void SetCertificatePrivateKeyPermissions(X509Certificate2 certificate, IdentityReference account, Operation operation)

  var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
  if (rsa != null)//ISSUE 1: rsa is NULL
  
    var cspParams = new CspParameters(rsa.CspKeyContainerInfo.ProviderType, rsa.CspKeyContainerInfo.ProviderName, rsa.CspKeyContainerInfo.KeyContainerName)
    
      Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore,
      CryptoKeySecurity = rsa.CspKeyContainerInfo.CryptoKeySecurity//ISSUE 2: There is no CryptoKeySecurity property present
    ;

    switch (operation)
    
      case Operation.Add:
        cspParams.CryptoKeySecurity.AddAccessRule(new CryptoKeyAccessRule(account, CryptoKeyRights.GenericRead, AccessControlType.Allow));
        break;
      case Operation.Remove:
        cspParams.CryptoKeySecurity.RemoveAccessRule(new CryptoKeyAccessRule(account, CryptoKeyRights.GenericAll, AccessControlType.Allow));
        break;
      default:
        throw new ArgumentException("Unhandled operation type");
    

    using (var rsa2 = new RSACryptoServiceProvider(cspParams))
    
      
    
  

【问题讨论】:

没有“.NET 5 框架”。只有 .NET 5。 【参考方案1】:

.NET 5 没有CryptoKeySecurity,因为它是特定于 Windows 的并且尚未移植(如果曾经计划移植的话)。关于您的问题的几句话:

    var rsa = certificate.PrivateKey as RSACryptoServiceProvider; -- 自 .NET Framework 4.6 起,此构造可被视为已过时且已弃用。如果您使用的是 4.6+,则在任何情况下都不应使用 RSACryptoServiceProvider。相反,您应该只访问X509Certificate2 class extension methods 来检索公钥/私钥句柄。更多详情见我的博文:Accessing and using certificate private keys in .NET Framework/.NET Core。

    在 Windows 上使用 X509Certificate2.GetRSAPrivateKey() 扩展方法时,它将返回一个 RSACng 类的实例,该类包含 Key 类型的 CngKey 属性。然后使用GetProperty和SetProperty方法读写Security Descr属性。如果键支持 ACL,您可以检查 Security Descr Support 属性(如果支持,则为 1,任何其他值表示该键不支持 ACL)。

【讨论】:

仅供参考,如果使用 FileSecurity/FileSystemAccessRule 将 CngKey 与 Microsoft Software Key Storage Provider 一起存储将正常工作,因为密钥存储为文件。我刚刚使用来自this SO answer 的代码使用 net5 应用程序完成了该操作

以上是关于在 .NET 5 中设置证书私钥权限的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 powershell 授予用户对证书私钥的权限?

在 Powershell 中设置 IIS 绑定证书时出现问题

在 .NET 4 中在 Root 中插入证书(带私钥),本地计算机证书存储失败

如何在 Jboss 5 中配置外部服务调用证书

如何在 IIS 中设置 HTTPS 服务

是否可以在本地服务器中设置受信任的 TLS 证书?