【发布时间】:2021-02-02 18:45:58
【问题描述】:
我正在制作一个自签名的 X509 证书,如下所示:
public X509Certificate2 GenerateSelfSignedCertificate(Guid customerId)
{
var distinguishedName = GetDistinguishedName(customerId);
var rsa = RSA.Create(KeySize);
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithm, Padding);
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
request.CertificateExtensions.Add(new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.DataEncipherment |
X509KeyUsageFlags.NonRepudiation, false));
var cert = request.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.Add(CertificateLifespan));
return cert;
}
然后我使用此方法生成证书并使用以下方法存储它:
public void StoreCertificate(X509Certificate2 certificate)
{
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
}
接下来,我尝试使用以下方法从证书存储中获取证书:
public X509Certificate2 FetchPrivateCertificate(Guid customerId)
{
var distinguishedName = GetDistinguishedName(customerId);
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, distinguishedName, false);
store.Close();
var privateCert = certs.OfType<X509Certificate2>().FirstOrDefault(x => x.HasPrivateKey);
return privateCert;
}
...使用相同的customerId,此结果始终为空。它甚至没有检查证书是否有私钥,证书集合总是空的。可分辨名称的生成方式完全相同。证书肯定在证书存储中。
我错过了什么?
更新
根据请求,我将添加专有名称的生成方式:
private string GetDistinguishedName(Guid customerId)
{
var domain = IPGlobalProperties.GetIPGlobalProperties().DomainName;
var domainDistinguishedName = string.Join(",DC=", domain.Split("."));
var distinguishedName = $"DC={Environment.MachineName},DC={domainDistinguishedName},O={customerId}";
return distinguishedName;
}
【问题讨论】:
-
distinguishedName变量的类型是什么? -
@Crypt32 这是一个字符串。
-
那么字符串与证书主题的格式化名称的主题不匹配。比如说,您的
distinguishedName可能看起来像CN=mysubject,O=example,C=us,但格式化的主题将是CN=mysubject, O=example, C=us(RDN 分隔符后有空格)。如果您能提供一个存储在变量中的内容以及返回证书的名称的示例,那就太好了。 -
@Crypt32 好的,我添加了它。我明白你在谈论空间,让我看看这是否有影响。
-
@Crypt32 是的,就是这样;当然不明显。如果你想写出来作为答案,我会接受。
标签: c# .net-standard x509certificate2