问题描述
过去,我一直通过导出带有密码的PFX证书来制作安全的TcpListener,但想知道是否可以跳过此步骤。
我没有使用商业SSL证书,而是使用根CA颁发服务器证书。这些服务器证书在C#中托管TcpListener时需要其他步骤(我想是因为未使用CSR)...但是,如果我确实拥有私钥和OpenSSL生成/使用的证书,该怎么办。
sslCertificate = new X509Certificate2( myExportedCert.pfx, 1234);
所以这很好,但是我必须发出openssl命令来从证书中创建pfx文件和私钥,然后组成一些密码。然后在我的代码中包含此密码。
我想知道此步骤是否非常必要。有没有办法从Cert组成X509Certificate2,然后应用私钥。构造函数参数仅允许Cert部分使用,但是由于没有私钥,加密操作随后失败。
此外,我也不想依赖OpenSSL或IIS进行导出pfx ....似乎很笨拙。
理想情况下,我想:
sslCertificate = new X509Certificate2( myCert.crt);
sslCertificate.ApplyPrivateKey(keyBytes)//< =或 private.key或任何
sslStream.AuthenticateAsServer(sslCertificate,false,SslProtocols.Default,false);
您要问几件事
为证书附加私钥
从.NET Framework开始您可以将4.7.2或.NET Core 2.0结合使用证书和密钥。它不会修改证书对象,而是生成一个知道密钥的新证书对象。
使用(X509Certificate2 pubOnly =新的X509Certificate2( myCert.crt))
使用(X509Certificate2 pubPrivEphemeral = pubOnly.CopyWithPrivateKey(privateKey))
{
//导出为PFX并重新导入,如果您想正常PFX私钥生存期
//(SslStream当前需要此步骤,但对于使用证书的大多数其他事物
//则不需要)
返回新的X509Certificate2(pubPrivEphemeral.Export(X509ContentType.Pfx ));
}
在.NET Framework(但不是.NET Core)上,如果您的私钥是 RSACryptoServiceProvider
或 DSACryptoServiceProvider
您可以使用 cert.PrivateKey = key
加载私钥
这一点较难,除非您已经解决过。
在大多数情况下,答案是在,但是如果您可以迁移到.NET Core 3.0,事情就会变得容易得多。
PKCS#8 PrivateKeyInfo
从.NET Core 3.0开始,您可以相对简单地做到这一点:
using(RSA rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(binaryEncoding,out _);
//现在用键做东西
}
(当然,如果您有PEM,则需要通过在BEGIN和END分隔符之间提取内容并通过 Convert.FromBase64String
运行它来 de-PEM,以获取 binaryEncoding
)。
PKCS#8 EncryptedPrivateKeyInfo
开始在.NET Core 3.0中,您可以相对简单地做到这一点:
使用(RSA rsa = RSA.Create())
{
rsa.ImportEncryptedPkcs8PrivateKey(password,binaryEncoding,out _);
//现在使用键进行填充
}
(如上所述,如果是PEM,则需要先去PEM。
PKCS#1 RSAPrivateKey
从.NET Core 3.0开始,您可以相对简单地完成此操作:
使用(RSA rsa = RSA.Create())
{
rsa.ImportRSAPrivateKey(binaryEncoding,out _);
//现在用键做东西
}
(相同的 de -PEM(如果是PEM)。
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.
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");
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.
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.
Also, I don't want to rely on OpenSSL or IIS to export the pfx.... seems clumsy.
Ideally i would like:
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.
Attaching a private key to a certificate
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));
}
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.
Loading the private key
This one is harder, unless you've already solved it.
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.
PKCS#8 PrivateKeyInfo
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
}
(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
).
PKCS#8 EncryptedPrivateKeyInfo
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
}
(as above, you need to "de-PEM" it first, if it was PEM).
PKCS#1 RSAPrivateKey
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
}
(same "de-PEM" if PEM).
这篇关于从Cert和Key创建X509Certificate2,而无需创建PFX文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!