过去,我一直通过导出带有密码的PFX证书来制作安全的TcpListener,但想知道是否可以跳过此步骤。
我没有使用商业SSL证书,而是拥有用于颁发服务器证书的RootCA。这些服务器证书在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) // <= or "private.key" or whatever
sslStream.AuthenticateAsServer(sslCertificate, false, SslProtocols.Default, false);
答案 0 :(得分:0)
您要解决的事情有很多不同,难易程度都不同。
从.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)上,如果您的私钥是RSACryptoServiceProvider
或DSACryptoServiceProvider
,则可以使用cert.PrivateKey = key
,但是它具有复杂的副作用,因此不建议使用。
除非您已经解决了这个问题,否则这会很难。
在大多数情况下,答案是在Digital signature in c# without using BouncyCastle中,但是如果可以迁移到.NET Core 3.0,事情将会变得容易得多。
从.NET Core 3.0开始,您可以相对简单地做到这一点:
using (RSA rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(binaryEncoding, out _);
// do stuff with the key now
}
(当然,如果您有PEM,则需要通过在BEGIN和END分隔符之间提取内容并通过Convert.FromBase64String
运行它来“去PEM”,以获得binaryEncoding
)。
从.NET Core 3.0开始,您可以相对简单地做到这一点:
using (RSA rsa = RSA.Create())
{
rsa.ImportEncryptedPkcs8PrivateKey(password, binaryEncoding, out _);
// do stuff with the key now
}
(如上所述,如果是PEM,则需要先对其进行“去PEM”操作。)
从.NET Core 3.0开始,您可以相对简单地做到这一点:
using (RSA rsa = RSA.Create())
{
rsa.ImportRSAPrivateKey(binaryEncoding, out _);
// do stuff with the key now
}
(如果是PEM,则相同的“ de-PEM”)。
答案 1 :(得分:0)
最后我做到了,它运行良好:
...
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);
...