簡體   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