繁体   English   中英

我尝试使用 dot-net 生成 X509Certificate2 密钥对,但缺少私钥

[英]I try to generate a X509Certificate2 key pair with dot-net but private key is missing

我尝试使用 dot-net 创建一个公私密钥对并将其安装在本地密钥库中。 当私钥没有与公钥一起安装时,我感到很困惑,然后我注意到尽管证书的HasPrivateKey属性设置为true但实际的PrivateKey属性为null 如何将私钥和公钥都添加到 Windows 密钥库? 稍后需要证书进行端口绑定。

我当前的代码基本上是这样的:

public static X509Certificate2 CreateSelfSigned(string issuer="", string firendly_name = "")
{
using (var key = RSA.Create(4096))
{
    var req = new CertificateRequest(
        $"CN={issuer}",
        key,
        HashAlgorithmName.SHA256,
        RSASignaturePadding.Pkcs1);
    
    req.CertificateExtensions.Add(
        new X509BasicConstraintsExtension(true, false, 0, true));

    req.CertificateExtensions.Add(
        new X509EnhancedKeyUsageExtension(
            new OidCollection
            {
                // Server Authentifikation
                new Oid("1.3.6.1.5.5.7.3.2"),
                // Client Authentifikation
                new Oid("1.3.6.1.5.5.7.3.1")
            },
            true));

    req.CertificateExtensions.Add(
        new X509SubjectKeyIdentifierExtension(req.PublicKey, false));


    var cert = req.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1),
        DateTimeOffset.UtcNow.AddYears(30));
    cert.FriendlyName = firendly_name;


    using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
    {
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);
        store.Close();
    }

}
}

我已经在互联网上搜索过,但找不到适合我的解决方案。 真的让我头疼好几个小时。 该程序是一种安装程序类型的程序,以前称为 PowerShell 以创建一个自签名证书,该证书只能在一半的时间内工作并且非常脏。 由于项目限制,我仅限于 dot-net 4.7.2 并且不能非常依赖外部库。

HasPrivateKey 属性设置为 true 实际 PrivateKey 属性为 null

您不应该信任或使用PrivateKey属性,对于基于 ECDSA/ECDH/DH 的证书,它始终为 null,对于 RSA 和 DSA,它也可以为 null(如您所见)。 GetRSAPrivateKey()方法(和其他方法,用于不同的算法)是更好的答案。

如何将私钥和公钥都添加到 Windows 密钥库?

问题是 CertificateRequest 将密钥按原样绑定到证书。 您有一个临时密钥(由RSA.Create(4096)创建),以便证书与临时密钥相关联。 当您将它添加到商店时,临时密钥就会被遗忘。

您可以更改您的密钥创建以创建一个命名的 CNG 密钥,或者只是将证书导出为 PFX,使用 PersistKeySet 重新导入它,然后将其添加到存储中。

var cert = req.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1),
    DateTimeOffset.UtcNow.AddYears(30));
cert.FriendlyName = firendly_name;

using (cert)
using (var tmpCert = new X509Certificate2(cert.Export(X509ContentType.Pfx), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet))
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
    store.Open(OpenFlags.ReadWrite);
    store.Add(tmpCert);
    store.Close();
}

不久前,我遇到了类似的问题,试图将证书从 docker 容器的代码自动添加到商店。

我使用的解决方案是使用 OpenSSL 工具创建自我证书并将其保存在项目内的文件夹中。 注意:我创建了一个 pfx 证书,以便在证书中包含私钥。

所以,我有一个像下面这样的代码

使用 (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.ReadWrite)) {

store.Add(new X509Certificate2("path-to-certificate/certificate-name.pfx", "certificatePassword"));

}

注意2:“StoreName.Root”和“StoreLocation.CurrentUser”将根据您要保存证书的商店而有所不同。

我希望你觉得这个解决方案有用!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM