C# 将私钥与.net中的X509Certificate2类关联
我正在编写一些创建X509证书和公钥/私钥对的代码。公钥被添加到证书中,并被发送到CA,CA对其进行签名 然后通过System.Security.Cryptography.X509Certificates.X509Certificate2类访问返回的证书。现在,我想使用此证书启动与其他客户端的安全连接。因此,我使用SslStream类。要启动SSL握手,我使用以下方法:C# 将私钥与.net中的X509Certificate2类关联,c#,.net,ssl,x509certificate,C#,.net,Ssl,X509certificate,我正在编写一些创建X509证书和公钥/私钥对的代码。公钥被添加到证书中,并被发送到CA,CA对其进行签名 然后通过System.Security.Cryptography.X509Certificates.X509Certificate2类访问返回的证书。现在,我想使用此证书启动与其他客户端的安全连接。因此,我使用SslStream类。要启动SSL握手,我使用以下方法: server.AssociatedSslStream.AuthenticateAsServer(
server.AssociatedSslStream.AuthenticateAsServer(
MyCertificate, // Client Certificate
true, // Require Certificate from connecting Peer
SslProtocols.Tls, // Use TLS 1.0
false // check Certificate revocation
);
此方法要求私钥与证书相关联。当然,CA返回的证书不包含私钥。但它作为.key文件存储在硬盘上。X509Certificate2类有一个名为PrivateKey的属性,我想它会将私钥与证书相关联,但我找不到设置此属性的方法
有什么方法可以将私钥与.net X509类相关联吗?对于其他有相同问题的人,我发现了一段简洁的代码,让您可以准确地执行以下操作: 编辑:助手方法的代码(否则需要codeproject登录)如下所示:
public static byte[] GetBytesFromPEM(string pemString, PemStringType type)
{
string header; string footer;
switch (type)
{
case PemStringType.Certificate:
header = "-----BEGIN CERTIFICATE-----";
footer = "-----END CERTIFICATE-----";
break;
case PemStringType.RsaPrivateKey:
header = "-----BEGIN RSA PRIVATE KEY-----";
footer = "-----END RSA PRIVATE KEY-----";
break;
default:
return null;
}
int start = pemString.IndexOf(header) + header.Length;
int end = pemString.IndexOf(footer, start) - start;
return Convert.FromBase64String(pemString.Substring(start, end));
}
您可以省去复制粘贴所有代码的麻烦,并将私钥存储在证书旁边的
pfx
/pkcs\12
文件中:
openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx
您必须提供密码,并将其传递给X509Certificate2的构造函数:
X509Certificate2 cert = new X509Certificate2("mycert.pfx","password");
我的解决方案
byte[] PublicCertificate = Encoding.Unicode.GetBytes("-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----");
var publicCertificate = new X509Certificate2(PublicCertificate );
byte[] PrivateKey = Convert.FromBase64String("MIIEvQIBA...=");
using var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(PrivateKey, out _);
publicCertificate = publicCertificate.CopyWithPrivateKey(rsa);
publicCertificate = new X509Certificate2(publicCertificate.Export(X509ContentType.Pkcs12));
var client = new RestClient("api_url");
client.ClientCertificates = new X509Certificate2Collection();
client.ClientCertificates.Add(publicCertificate);
这救了我!创建了pfx,但没有意识到我还需要向构造函数提供密码。回答得很好!我用它来避免通过MMC插件注册证书的麻烦。你可以通过在openSSL命令中添加“-passout pass:”来避免密码。这应该标记为真正的答案,因为这是真正的方法。我从哪里获得openSSL?这是一种比将私钥和证书捆绑在一起更好的方法,我已经使用了这个选项,并且发现它是一个更好的选择。如果您愿意告诉我们这个优势的本质,请包含帮助器方法的代码,让人恼火的是必须在外部站点上创建一个用户才能访问。尝试使用它,但是(当然)没有加密类(System.Web.Helpers中有一个-非常确定不是它…)这里缺少using?我在尝试在.NET Core 2控制台应用程序中设置证书的私钥时抛出了PlatformNotSupportedException
。这是否回答了您的问题?
byte[] PublicCertificate = Encoding.Unicode.GetBytes("-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----");
var publicCertificate = new X509Certificate2(PublicCertificate );
byte[] PrivateKey = Convert.FromBase64String("MIIEvQIBA...=");
using var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(PrivateKey, out _);
publicCertificate = publicCertificate.CopyWithPrivateKey(rsa);
publicCertificate = new X509Certificate2(publicCertificate.Export(X509ContentType.Pkcs12));
var client = new RestClient("api_url");
client.ClientCertificates = new X509Certificate2Collection();
client.ClientCertificates.Add(publicCertificate);