簡體   English   中英

從證書和密鑰創建 X509Certificate2,無需制作 PFX 文件

[英]Create X509Certificate2 from Cert and Key, without making a PFX file

過去,我一直通過導出帶有密碼的 PFX 證書來制作安全的 TcpListener,但想知道是否可以跳過此步驟。

我沒有使用商業 SSL 證書,並且有一個用於頒發服務器證書的根 CA。 在 C# 中托管 TcpListener 時,這些服務器證書需要額外的步驟(我猜是因為沒有使用 CSR)……但是如果我有私鑰和 OpenSSL 生成/使用的證書怎么辦。

sslCertificate = new X509Certificate2("myExportedCert.pfx", "1234");

所以這很棒,但是我必須發出 openssl 命令從證書和私鑰制作 pfx 文件,然后制作一些密碼。 然后在我的代碼中包含這個密碼。

我想知道這一步是否很有必要。 有沒有辦法從證書中組成一個X509Certificate2,然后應用私鑰。 構造函數參數只允許 Cert 部分,但加密失敗,因為沒有私鑰。

另外,我不想依賴 OpenSSL 或 IIS 來導出 pfx.... 看起來很笨拙。

理想情況下,我想:

sslCertificate = new X509Certificate2("myCert.crt");
sslCertificate.ApplyPrivateKey(keyBytes) // <= or "private.key" or whatever

sslStream.AuthenticateAsServer(sslCertificate, false, SslProtocols.Default, false);

有幾種不同的東西,你要求,不同程度的輕松。

將私鑰附加到證書

從 .NET Framework 4.7.2 或 .NET Core 2.0 開始,您可以組合證書和密鑰。 它不會修改證書對象,而是生成一個知道密鑰的新證書對象。

using (X509Certificate2 pubOnly = new X509Certificate2("myCert.crt"))
using (X509Certificate2 pubPrivEphemeral = pubOnly.CopyWithPrivateKey(privateKey))
{
    // Export as PFX and re-import if you want "normal PFX private key lifetime"
    // (this step is currently required for SslStream, but not for most other things
    // using certificates)
    return new X509Certificate2(pubPrivEphemeral.Export(X509ContentType.Pfx));
}

在 .NET Framework(但不是 .NET Core)上,如果您的私鑰是RSACryptoServiceProviderDSACryptoServiceProvider您可以使用cert.PrivateKey = key ,但這會產生復雜的副作用,因此不鼓勵使用。

加載私鑰

這個更難,除非你已經解決了。

大多數情況下,答案是在c# 中使用數字簽名而不使用 BouncyCastle ,但是如果您可以遷移到 .NET Core 3.0,事情就會變得容易得多

PKCS#8 私鑰信息

從 .NET Core 3.0 開始,您可以相對簡單地執行此操作:

using (RSA rsa = RSA.Create())
{
    rsa.ImportPkcs8PrivateKey(binaryEncoding, out _);
    // do stuff with the key now
}

(當然,如果你有一個 PEM,你需要通過提取 BEGIN 和 END 分隔符之間的內容並通過Convert.FromBase64String運行它來“de-PEM”它以獲得binaryEncoding )。

PKCS#8 加密私鑰信息

從 .NET Core 3.0 開始,您可以相對簡單地執行此操作:

using (RSA rsa = RSA.Create())
{
    rsa.ImportEncryptedPkcs8PrivateKey(password, binaryEncoding, out _);
    // do stuff with the key now
}

(如上所述,如果它是 PEM,您需要先“取消 PEM”)。

PKCS#1 RSAPrivateKey

從 .NET Core 3.0 開始,您可以相對簡單地執行此操作:

using (RSA rsa = RSA.Create())
{
    rsa.ImportRSAPrivateKey(binaryEncoding, out _);
    // do stuff with the key now
}

(如果 PEM,則相同的“de-PEM”)。

最后我做了這個,它工作正常:

...
if (!File.Exists(pfx)) {
    // Generate PFX
    string arguments = "openssl pkcs12 -export -in " + certPath + "" + certFile + ".crt -inkey " + certPath + "" + certFile + ".key -out " + certPath + "" + certFile + ".pfx -passout pass:" + pfxPassword;
    ProcessStartInfo opensslPsi = new ProcessStartInfo("sudo", arguments);
    opensslPsi.UseShellExecute = false;
    opensslPsi.RedirectStandardOutput = true;
    using (Process p = Process.Start(opensslPsi)) {
        p.WaitForExit();
    }
    // Set Permission
    ProcessStartInfo chmodPsi = new ProcessStartInfo("sudo", "chmod 644 " + certPath + "" + certFile + ".pfx");
    chmodPsi.UseShellExecute = false;
    chmodPsi.RedirectStandardOutput = true;
    using (Process p = Process.Start(chmodPsi)) {
        p.WaitForExit();
    }
}
sslCertificate = new X509Certificate2(pfx, pfxPassword);
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM