X.509与您在.Net Core中的力量

图片


前段时间,我想知道是否可以在不依靠openssl实用程序的情况下建立证书工厂如何从密钥生成到认证的整个过程“从按钮开始”。展望未来,我将说这方面System.Security.Cryptography空间是完全自给自足的。在本文中,我将考虑以下步骤:创建证书,导出为pempkcs12格式,将证书存储在文件系统中以及仅使用System.Security.Cryptography中的类进行身份验证的步骤


生物


在本文中,我将考虑一个没有证书颁发机构的简单的客户端-服务器交互方案。为了进行相互身份验证,我们需要根自签名证书caCert以及两个终端clientCertserverCert客户交换他们的证书,成功进行根身份验证。创建证书的步骤与任何openssl手册相同


  1. 生成一个非对称密钥:


    var rsaKey = RSA.Create(2048);

  2. 我们描述认证的主题:


    string subject = "CN=myauthority.ru";

    cn – “common name”, , , . , . MSDN "C = US/O = Microsoft/OU = WGA/CN = test".


  3. :


    var certReq = new CertificateRequest(subject, rsaKey,HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);

    Pkcs1 openssl.


  4. :


    certReq.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true)); 
    certReq.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certReq.PublicKey, false));

    , , SKI ( ).


  5. 5 :


    var expirate = DateTimeOffset.Now.AddYears(5);
    var caCert  = certReq.CreateSelfSigned(DateTimeOffset.Now, expirate);


.


  1. :


    var clientKey = RSA.Create(2048);
    string subject = "CN=10.10.10.*";
    var clientReq = new CertificateRequest(subject, clientKey,HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);

    ip , .


  2. :


    clientReq.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
    clientReq.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation, false));
    clientReq.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(clientReq.PublicKey, false));

  3. :


    byte[] serialNumber = BitConverter.GetBytes(DateTime.Now.ToBinary());

    Serial Number – , , . , .


  4. 5 :


    var clientCert = clientReq.Create(caCert, DateTimeOffset.Now, expirate, serialNumber):

    , . , caCert.Subject clientCert.Issuer, , .




, , . openssl pem, public.crt private.key. X509Certificate2, . , , base64 :


StringBuilder builder = new StringBuilder();
builder.AppendLine("-----BEGIN CERTIFICATE-----");
builder.AppendLine(Convert.ToBase64String(cert.RawData, Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine("-----END CERTIFICATE-----");
File.WriteAllText("public.crt", builder.ToString());

:


RSA key = (RSA)cert.PrivateKey;
string name = key.SignatureAlgorithm.ToUpper();
StringBuilder builder = new StringBuilder();
builder.AppendLine($"-----BEGIN {name} PRIVATE KEY-----");
builder.AppendLine(Convert.ToBase64String(key.ExportRSAPrivateKey(), Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine($"-----END {name} PRIVATE KEY-----");
File.WriteAllText("private.key", builder.ToString());

, ExportRSAPrivateKey netcore 3.0, .


pkcs12 pfx, . X509Certificate2 Export, X509ContentType.Pkcs12 X509ContentType.Pfx. , , cert.HasPrivateKey == false. , X509Certificate2 , , . . p12 pfx, :


var exportCert = new X509Certificate2(cert.Export(X509ContentType.Cert), (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet).CopyWithPrivateKey((RSA)cert.PrivateKey);
File.WriteAllBytes("client.pfx", exportCert.Export(X509ContentType.Pfx));
File.WriteAllBytes("client.p12", exportCert.Export(X509ContentType.Pkcs12));

Export .


.net core , X509Store. :


X509Store store = new X509Store("test");
store.Open(OpenFlags.ReadWrite);
store.Add(cert);

OC Linux "~/.dotnet/corefx/cryptography/x509stores/ test/" "827...E3E.pfx", ( Thumbprint). - openssl , . *.pfx , . X509Store , IssueName .



. , https. , . . « », , — , .
nginx :


server {
        listen 443;
        ssl on;
        ssl_certificate /etc/nginx/ssl/public.crt;
        ssl_certificate_key /etc/nginx/ssl/private.key;
        ssl_client_certificate /etc/nginx/ssl/caCert.crt;
        ssl_verify_client on;
}

HttpClient:


SocketsHttpHandler handler = new SocketsHttpHandler();
handler.SslOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
 {
    X509Chain chain = new X509Chain(false);
    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
    chain.ChainPolicy.ExtraStore.Add(caCert);
    var serverert = new X509Certificate2(certificate);
    return chain.Build(serverert);
};
handler.SslOptions.ClientCertificates = new X509CertificateCollection() { clientCert };
HttpClient client = new HttpClient(handler);
var resp = await client.GetAsync…

"" "" .



.net core Linux OpenSSL. . , BouncyCastle, , , , 10 . , , X.509.


All Articles