我正在学习通过nuget包对证书签名请求和服务器进行签名
System.Security.Cryptography.Cng
是的。还有什么比重新创造一个更好的方法。似乎有一个块我目前没有绕过,那就是服务器签名方,即在下面的代码中
System.InvalidOperationException: 'An X509Extension with OID '2.5.29.37' has already been specified.'
在
request.Create(
在using子句中。我看到在
http://oid-info.com/get/2.5.29.37
它是关于扩展密钥使用的。
问题:
-
这个
MakeLocalhostCert
很可能是错误的,应该更改什么使其成为签署CSR的证书?
-
是否可以在返回的csr中添加/删除扩展/oid?我相信是的,但不知怎么的,这一部分目前我躲开了。
我用了
https://stackoverflow.com/users/6535399/bartonjs
在
https://stackoverflow.com/a/45240640/1332416
在
https://stackoverflow.com/a/44073726/1332416
才能走到这一步。:)
private static void CsrSigningTest()
{
using(ECDsa privateClientEcdsaKey = ECDsa.Create(ECCurve.NamedCurves.nistP256))
{
CertificateRequest request = new CertificateRequest(
new X500DistinguishedName("CN=example.com, O=Example Ltd, OU=AllOver, L=Sacremento, ST=\"California\", C=US, E=some@example.com"),
privateClientEcdsaKey,
HashAlgorithmName.SHA256);
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("example.com");
request.CertificateExtensions.Add(sanBuilder.Build());
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.8") }, false));
byte[] derEncodedCsr = request.CreateSigningRequest();
var csrSb = new StringBuilder();
csrSb.AppendLine("-----BEGIN CERTIFICATE REQUEST-----");
csrSb.AppendLine(Convert.ToBase64String(derEncodedCsr));
csrSb.AppendLine("-----END CERTIFICATE REQUEST-----");
var csr = csrSb.ToString();
byte[] serial = new byte[16];
using(var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(serial);
}
DateTimeOffset notBefore = DateTimeOffset.UtcNow;
DateTimeOffset notAfter = notBefore.AddYears(1);
var issuerCertificate = MakeLocalhostCert();
using(X509Certificate2 responseToCsr = request.Create(issuerCertificate, notBefore, notAfter, serial))
{
var csrResSb = new StringBuilder();
csrResSb.AppendLine("-----BEGIN CERTIFICATE-----");
csrResSb.AppendLine(Convert.ToBase64String(responseToCsr.GetRawCertData()));
csrResSb.AppendLine("-----END CERTIFICATE-----");
var signedCert = csrResSb.ToString();
}
}
}
private static X509Certificate2 MakeLocalhostCert()
{
using(ECDsa key = ECDsa.Create(ECCurve.NamedCurves.nistP384))
{
var request = new CertificateRequest(
"CN=localhost",
key,
HashAlgorithmName.SHA384);
request.CertificateExtensions.Add(
new X509BasicConstraintsExtension(true, false, 0, true));
const X509KeyUsageFlags endEntityTypicalUsages =
X509KeyUsageFlags.DataEncipherment |
X509KeyUsageFlags.KeyEncipherment |
X509KeyUsageFlags.DigitalSignature |
X509KeyUsageFlags.NonRepudiation |
X509KeyUsageFlags.KeyCertSign;
request.CertificateExtensions.Add(
new X509KeyUsageExtension(endEntityTypicalUsages, true));
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("localhost");
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
request.CertificateExtensions.Add(sanBuilder.Build());
DateTimeOffset now = DateTimeOffset.UtcNow.AddMinutes(-1);
return request.CreateSelfSigned(now, now.AddYears(2));
}
}
<编辑:
一旦我应用了有关oid的修复并将最后一个位更改为
using(X509Certificate2 responseToCsr = request.Create(issuerCertificate, notBefore, notAfter, serial))
{
request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(issuerCertificate.PublicKey, false));
var csrResSb = new StringBuilder();
csrResSb.AppendLine("-----BEGIN CERTIFICATE-----");
csrResSb.AppendLine(Convert.ToBase64String(responseToCsr.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
csrResSb.AppendLine("-----END CERTIFICATE-----");
var signedCert = csrResSb.ToString();
}
我拿到一张证书
signedCert
这看起来像是已经签署的企业社会责任。如果从实际的csr文件中读取,则缺少的部分将是构造csr。
<编辑2:
Corefx GH中存在一个问题,跟踪这里涉及的一些问题:
Security crypto - Roadmap
是的。