
前段时间,我想知道是否可以在不依靠openssl实用程序的情况下建立证书工厂。如何从密钥生成到认证的整个过程“从按钮开始”。展望未来,我将说这方面的System.Security.Cryptography空间是完全自给自足的。在本文中,我将考虑以下步骤:创建证书,导出为pem和pkcs12格式,将证书存储在文件系统中以及仅使用System.Security.Cryptography中的类进行身份验证的步骤。
生物
在本文中,我将考虑一个没有证书颁发机构的简单的客户端-服务器交互方案。为了进行相互身份验证,我们需要根自签名证书caCert以及两个终端clientCert和serverCert。客户交换他们的证书,成功进行根身份验证。创建证书的步骤与任何openssl手册相同:
生成一个非对称密钥:
var rsaKey = RSA.Create(2048);
我们描述认证的主题:
string subject = "CN=myauthority.ru";
cn – “common name”, , , . , . MSDN "C = US/O = Microsoft/OU = WGA/CN = test".
:
var certReq = new CertificateRequest(subject, rsaKey,HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);
Pkcs1 openssl.
:
certReq.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
certReq.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certReq.PublicKey, false));
, , SKI ( ).
5 :
var expirate = DateTimeOffset.Now.AddYears(5);
var caCert = certReq.CreateSelfSigned(DateTimeOffset.Now, expirate);
.
:
var clientKey = RSA.Create(2048);
string subject = "CN=10.10.10.*";
var clientReq = new CertificateRequest(subject, clientKey,HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);
ip , .
:
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));
:
byte[] serialNumber = BitConverter.GetBytes(DateTime.Now.ToBinary());
Serial Number – , , . , .
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.