【问题标题】:How to provide X509KeyStorageFlags to CertificateRequest如何向 CertificateRequest 提供 X509KeyStorageFlags
【发布时间】:2021-03-18 01:40:51
【问题描述】:

可以在 X509Certificate2 构造函数中指定 X509KeyStorageFlags,如下所示:

    var cert = new X509Certificate2(bytes, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

但在我的情况下,我使用 CertificateRequest 创建自签名证书,因此我没有证书构造函数:

var rsaKeyPair = RSA.Create();
var request = new CertificateRequest(
                      $"cn = {Environment.MachineName}",
                      rsaKeyPair,
                      HashAlgorithmName.SHA256,
                      RSASignaturePadding.Pkcs);

request.CertificateExtensions.Add(
                new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment |
                                          X509KeyUsageFlags.DigitalSignature, true));

var certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow),
                                           new DateTimeOffset(DateTime.UtcNow.AddYears(2)));

有没有办法将 KeyStorageFags 添加到 request.CertificateExtension 或类似的东西?

【问题讨论】:

  • 有一个构造函数:public X509Certificate2 (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
  • 键选项应该传递给键对象:var rsaKeyPair = RSA.Create();

标签: c# x509certificate2


【解决方案1】:

如何向 CertificateRequest 提供 X509KeyStorageFlags

CertificateRequest 对密钥存储一无所知。它所做的只是构建证书,然后调用cert.CopyWithPrivateKey(privateKey)

移动目标:

如何向 CopyWithPrivateKey 提供 X509KeyStorageFlags

CopyWithPrivateKey 复制当前状态的密钥。临时密钥保持短暂。持久化密钥保持持久化。

移动目标:

如何向 RSA.Create() 提供 X509KeyStorageFlags

RSA.Create() 总是创建临时密钥,它根本不理解密钥存储。您必须使用理解持久性的特定 RSA 实现——但这会将您锁定在 Windows 中(当然,您的调用代码可能因操作系统而异)。

RSA rsaKeyPair = BuildMachinePersistedKeyPair(2048);

...

private static RSA BuildMachinePersistedKeyPair(int keySize)
{
    CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
    {
        ExportPolicy = CngExportPolicies.Exportable,
        Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
        KeyCreationOptions =
            CngKeyCreationOptions.OverwriteExistingKey |
            CngKeyCreationOptions.MachineKey,
    };

    CngProperty keySizeProperty = new CngProperty(
        KeyPropertyName.Length,
        BitConverter.GetBytes(keySize),
        CngPropertyOptions.None);

    creationParameters.Parameters.Add(keySizeProperty);

    using (CngKey cngKey = CngKey.Create(CngAlgorithm.Rsa, Guid.NewGuid().ToString(), creationParameters))
    {
        return new RSACng(cngKey);
    }
}

有没有更简单的方法?

当然,只需导出/导入临时的。

X509Certificate2 certificate;

using (X509Certificate2 ephemeral = request.CreateSelfSigned(...))
{
    certificate = new X509Certificate2(
        ephemeral.Export(X509ContentType.Pkcs12),
        string.Empty,
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
}

【讨论】:

  • 所以我选择了你所说的简单方法。发生的情况是 request.CreateSelfSigned() 创建证书(1 个分配)而不是调用返回 certificate.CopyWithPrivateKey(key)(2 个分配)而不是我调用 new X509Certificate(cert, password, keys) 返回所需的证书对象(3 个分配)。好吧,这基本上就是我问这个问题的原因。我认为CreateSelfSigned() 是我的构建器功能,尽管我做错了,因为我无法一次性传达所需的对象。但事实证明它不是那样工作的。谢谢
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多