将私钥与.net中的X509Certificate2类相关联

Pog*_*ips 23 .net c# ssl x509certificate

我正在研究一些创建X509certificate和公钥/私钥对的代码.公钥被添加到证书中,并将其发送给签署它的CA.

然后通过System.Security.Cryptography.X509Certificates.X509Certificate2类访问返回的证书.现在,我想使用此证书启动与其他客户端的安全连接.因此我使用SslStream类.要启动SSL握手,我使用以下方法:

server.AssociatedSslStream.AuthenticateAsServer(
                        MyCertificate,                      // Client Certificate
                        true,                               // Require Certificate from connecting Peer
                        SslProtocols.Tls,                   // Use TLS 1.0
                        false                               // check Certificate revocation
                    );
Run Code Online (Sandbox Code Playgroud)

此方法要求私钥与证书关联.当然,CA返回的证书不包含私钥.但它作为.key文件存储在硬盘上.X509Certificate2类有一个名为PrivateKey的属性,我想将私钥与证书关联,但我找不到设置此属性的方法.

有没有办法可以将私钥与.net X509类关联起来?

ssc*_*ber 37

您可以省去复制粘贴所有代码的麻烦,并将证书旁边的私钥存储在pfx/ pkcs#12file中:

openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx
Run Code Online (Sandbox Code Playgroud)

您必须提供密码,您必须将密码传递给以下构造函数X509Certificate2:

X509Certificate2 cert = new X509Certificate2("mycert.pfx","password");
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过在openSSL命令中添加“ -passout pass:”来避免使用密码 (2认同)

Pog*_*ips 17

对于遇到同样问题的其他人,我找到了一个简洁的代码,让你做到这一点:

http://www.codeproject.com/Articles/162194/Certificates-to-DB-and-Back

byte[] certBuffer = Helpers.GetBytesFromPEM(publicCert, PemStringType.Certificate);
byte[] keyBuffer  = Helpers.GetBytesFromPEM(privateKey, PemStringType.RsaPrivateKey);

X509Certificate2 certificate = new X509Certificate2(certBuffer, password);

RSACryptoServiceProvider prov = Crypto.DecodeRsaPrivateKey(keyBuffer);
certificate.PrivateKey = prov;
Run Code Online (Sandbox Code Playgroud)

编辑:Helper方法的代码(否则需要代码项目登录)如下:

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

  • 试图使用它,但(当然)没有Crypto类(在System.Web.Helpers中有一个 - 非常肯定不是..)这里有一个使用缺失? (7认同)
  • 尝试在.NET Core 2控制台应用程序中设置证书的私钥时,抛出“ PlatformNotSupportedException”。 (3认同)
  • 包括帮助方法的代码,烦人的是必须在外部站点上创建用户才能访问. (2认同)

lin*_*lin 9

我的解决方案

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

  • `ImportPkcs8PrivateKey` 是 .NET Core - 在 .NET Framework 4.8 中不可用? (2认同)
  • @lin,您的解决方案有助于消除我的 /sf/ask/4994069531/ 错误。我所做的唯一更改是将“ImportPkcs8PrivateKey”替换为“ImportRSAPrivateKey”。这里 /sf/answers/4909282521/ 就是我将“ImportPkcs8PrivateKey”更改为“ImportRSAPrivateKey”的答案。 (2认同)