问题描述
过去我一直通过导出带有密码的 PFX 证书来制作安全的 TcpListener,但想知道是否可以跳过此步骤.
In the past I have been making secure TcpListener by exporting a PFX certificate with a password, but would like to know if this step could be skipped.
我没有使用商业 SSL 证书,并且有一个根 CA,用于颁发服务器证书.在 C# 中托管 TcpListener 时,这些服务器证书需要额外的步骤(我猜是因为没有使用 CSR)......但是如果我确实有私钥和 OpenSSL 生成/使用的证书怎么办.
I'm not using commercial SSL certificates, and have a Root CA, that I use to issue server certificates. These server certificates require additional steps when hosting a TcpListener in C# (I guess because the CSR wasn't used)... but what if I do have the Private Key, and the Certificate that OpenSSL generates/uses.
sslCertificate = new X509Certificate2("myExportedCert.pfx", "1234");
所以这很好,但是我必须发出一个 openssl 命令来从证书和私钥制作一个 pfx 文件,然后组成一些密码.然后将此密码包含在我的代码中.
So this is great, however I have to issue an openssl command to make a pfx file from the Certificate and the Private Key, then make up some password. Then include this password in my code.
我想知道这一步是否非常必要.有没有办法从证书中组成一个 X509Certificate2,然后应用私钥.构造函数参数只允许 Cert 部分,但由于没有私钥,加密失败.
I was wondering if this step was quite necessary. Is there a way to make up a X509Certificate2 from the Cert, and then apply the Private Key. The constructor arguments allow the Cert only part, but encrypting fails then because there is no private key.
另外,我不想依赖 OpenSSL 或 IIS 来导出 pfx.... 看起来很笨拙.
Also, I don't want to rely on OpenSSL or IIS to export the pfx.... seems clumsy.
理想情况下,我希望:
sslCertificate = new X509Certificate2("myCert.crt");
sslCertificate.ApplyPrivateKey(keyBytes) // <= or "private.key" or whatever
sslStream.AuthenticateAsServer(sslCertificate, false, SslProtocols.Default, false);
推荐答案
你有几个不同的要求,不同程度的轻松.
There are a couple of different things you're asking for, with different levels of ease.
从 .NET Framework 4.7.2 或 .NET Core 2.0 开始,您可以结合使用证书和密钥.它不会修改证书对象,而是生成一个知道密钥的新证书对象.
Starting in .NET Framework 4.7.2 or .NET Core 2.0 you can combine a cert and a key. It doesn't modify the certificate object, but rather produces a new cert object which knows about the key.
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)上,如果您的私钥是 RSACryptoServiceProvider
或 DSACryptoServiceProvider
,您可以使用 cert.PrivateKey = key
,但有复杂的副作用,不鼓励这样做.
on .NET Framework (but not .NET Core) if your private key is RSACryptoServiceProvider
or DSACryptoServiceProvider
you can use cert.PrivateKey = key
, but that has complex side-effects and is discouraged.
这个比较难,除非你已经解决了.
This one is harder, unless you've already solved it.
在大多数情况下,这个问题的答案在 不使用 BouncyCastle 的 c# 中的数字签名中,但如果你可以移动到 .NET Core 3.0 的事情变得容易多了.
For the most part the answer for this is in Digital signature in c# without using BouncyCastle, but if you can move to .NET Core 3.0 things get a lot easier.
从 .NET Core 3.0 开始,您可以相对简单地做到这一点:
Starting in .NET Core 3.0 you can do this relatively simply:
using (RSA rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(binaryEncoding, out _);
// do stuff with the key now
}
(当然,如果你有一个 PEM,你需要通过提取 BEGIN 和 END 分隔符之间的内容并通过 Convert.FromBase64String
运行它来de-PEM"它以获得binaryEncoding
).
(of course, if you had a PEM you need to "de-PEM" it, by extracting the contents between the BEGIN and END delimiters and running it through Convert.FromBase64String
in order to get binaryEncoding
).
从 .NET Core 3.0 开始,您可以相对简单地做到这一点:
Starting in .NET Core 3.0 you can do this relatively simply:
using (RSA rsa = RSA.Create())
{
rsa.ImportEncryptedPkcs8PrivateKey(password, binaryEncoding, out _);
// do stuff with the key now
}
(如上,如果是 PEM,您需要先去 PEM"它).
(as above, you need to "de-PEM" it first, if it was PEM).
从 .NET Core 3.0 开始,您可以相对简单地做到这一点:
Starting in .NET Core 3.0 you can do this relatively simply:
using (RSA rsa = RSA.Create())
{
rsa.ImportRSAPrivateKey(binaryEncoding, out _);
// do stuff with the key now
}
(如果是 PEM,则相同的de-PEM").
(same "de-PEM" if PEM).
这篇关于从 Cert 和 Key 创建 X509Certificate2,而不制作 PFX 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!