从Cert和Key创建X509Certificate2,而无需创建PFX文件

Con*_*rad 4 ssl certificate x509certificate2

过去,我一直通过导出带有密码的PFX证书来确保TcpListener的安全,但是我想知道是否可以跳过此步骤。

我没有使用商业SSL证书,而是使用了根CA颁发服务器证书。这些服务器证书在C#中托管TcpListener时需要其他步骤(我想是因为未使用CSR)...但是,如果我确实拥有私钥和OpenSSL生成/使用的证书,该怎么办。

sslCertificate = new X509Certificate2("myExportedCert.pfx", "1234");
Run Code Online (Sandbox Code Playgroud)

因此,这很好,但是我必须发出openssl命令,以根据证书和私钥创建pfx文件,然后输入一些密码。然后在我的代码中包含此密码。

我想知道此步骤是否必要。有没有办法从Cert组成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);
Run Code Online (Sandbox Code Playgroud)

bar*_*njs 6

您要解决的事情有很多不同,难易程度不同。

将私钥附加到证书

从.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));
}
Run Code Online (Sandbox Code Playgroud)

.NET Framework(而不是.NET Core)在.NET Framework(而不是.NET Core)上运行,如果您的私钥是RSACryptoServiceProviderDSACryptoServiceProvider可以使用cert.PrivateKey = key,则具有复杂的副作用并且不建议使用。

加载私钥

除非您已解决,否则此难度会更大。

在很大程度上,答案是在不使用BouncyCastle的情况下使用c#进行数字签名,但是,如果可以迁移到.NET Core 3.0,事情将会变得容易得多

PKCS#8 PrivateKeyInfo

从.NET Core 3.0开始,您可以相对简单地执行此操作:

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

(当然,如果您有PEM,则需要通过提取BEGIN和END分隔符之间的内容并进行遍历Convert.FromBase64String以获取binaryEncoding)来“ de-PEM” 。

PKCS#8 EncryptedPrivateKeyInfo

从.NET Core 3.0开始,您可以相对简单地执行此操作:

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

(如上所述,如果是PEM,则需要先对其进行“ de-PEM”处理)。

PKCS#1 RSAPrivateKey

从.NET Core 3.0开始,您可以相对简单地执行此操作:

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

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

  • 谢谢@bartonjs,如果我使用.NET Core,请按此使用-现在,我将仅使用Process()来获取OpenSSL来创建.pfx文件,因为我有.crt和.key文件手。(在.NET4中不可用,这似乎很奇怪-似乎很基本的要求,即能够使用CA,证书和私钥托管安全的TCP服务) (2认同)