无法将X509Certificate2及其私钥保存在X509Store中

问题描述 投票:0回答:1

我试图远离

CERTENROLLLib
,我一直在尝试使用普通的.NET8
CertificateRequest
来生成CSR,取回证书并在存储之前将私钥重新集成回证书中回到 Windows 的
X509Store
StoreName.My

我这里的代码,当我调试它们时,它显示私钥回到了证书中,但是在存储它之后,我无法使用其私钥导出证书......基本上不存在。有没有一种方法可以存档我在这里描述的内容?

public static readonly X509KeyStorageFlags InstallFlags = X509KeyStorageFlags.Exportable |
                                                          X509KeyStorageFlags.PersistKeySet |
                                                          X509KeyStorageFlags.UserKeySet;

byte[] rawData = Convert.FromBase64String(x509Base64);
using (X509Certificate2 tmp = new X509Certificate2(rawData, "", InstallFlags))
{
    string pubKey = Convert.ToBase64String(tmp.PublicKey.EncodedKeyValue.RawData);

    SomeTempCryptoDictionary.TryGetValue(pubKey, out var crypto);
    using (X509Certificate2 certWithPrivateKey = tmp.CopyWithPrivateKey((RSA) crypto))
    using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
    {
        store.Open(OpenFlags.ReadWrite);
        store.Add(certWithPrivateKey);
        store.Close();

        certWithPrivateKey.Reset();
    }
}

我不确定是否允许我在那里输入空密码,但它没有抱怨,也没有抛出任何错误,我绝对不能通过

null
。这感觉就像,我真的很接近让它工作,而无需
CERTENROLLLib
只是不确定我还缺少什么......?

这是使用

CertificateRequest
生成CSR的部分。

RSA rsa = RSA.Create(2048);
X500DistinguishedName dn = new X500DistinguishedName("CN=HelloWorld");
CertificateRequest csr = new CertificateRequest(dn, rsa,
                                                HashAlgorithmName.SHA256,
                                                RSASignaturePadding.Pkcs1);
string pubKey = Convert.ToBase64String(csr.PublicKey.EncodedKeyValue.RawData);
// saved to be use when it comes back
SomeTempCryptoDictionary.Add(pubKey, rsa);

return Convert.ToBase64String(csr.CreateSigningRequest());
c# windows cryptography .net-8.0 x509certificate2
1个回答
0
投票

在你的行中:

using (var certExportable = new X509Certificate2(certWithPrivateKey.GetRawCertData(), "", InstallFlags))

您应该使用

certWithPrivateKey.Export(X509ContentType.Pkcs12)
而不是
.GetRawCertData()
。您调用的方法导出没有私钥的证书;您需要它是 PKCS#12/PFX 才能同时拥有证书和私钥。

您应该能够轻松地看到这一点,因为

certExportable.HasPrivateKey
当前应该为 false,但一旦更改导出格式,它将为 true。

当然,这确实要求私钥对象 (

crypto
) 已经代表可导出的密钥。

© www.soinside.com 2019 - 2024. All rights reserved.