对于我的一个应用程序(OPC UA数据服务器),我正在生成自签名证书。我必须为每个配置生成一个。
以下是该代的代码:
public static X509Certificate2 GenerateCertificate(string name, string applicationUri)
{
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), RANDOM);
certificateGenerator.SetSerialNumber(serialNumber);
X509Name x509Name = new X509Name($"C=XX, O=YYYYY, OU=ZZZZ, CN={name}");
certificateGenerator.SetIssuerDN(x509Name);
certificateGenerator.SetSubjectDN(x509Name);
certificateGenerator.SetNotBefore(DateTime.UtcNow.Date.AddDays(-1));
certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(CERTIFICATE_VALIDATE_YEARS));
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false,
new GeneralNames(new GeneralName[]
{
new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri),
new GeneralName(GeneralName.DnsName, Dns.GetHostName())
}));
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth));
certificateGenerator.AddExtension(X509Extensions.KeyUsage, true,
new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyEncipherment | KeyUsage.DataEncipherment | KeyUsage.KeyCertSign));
KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(RANDOM, STRENGTH);
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory(SIGNATURE_ALGORITHM, issuerKeyPair.Private);
X509Certificate bouncyCert = certificateGenerator.Generate(signatureFactory);
X509Certificate2 certificate;
Pkcs12Store store = new Pkcs12StoreBuilder().Build();
store.SetKeyEntry(name, new AsymmetricKeyEntry(subjectKeyPair.Private), new[] {new X509CertificateEntry(bouncyCert)});
string certificateUniqueId = Guid.NewGuid().ToString("x");
using (MemoryStream ms = new MemoryStream())
{
store.Save(ms, certificateUniqueId.ToCharArray(), RANDOM);
certificate = new X509Certificate2(ms.ToArray(), certificateUniqueId, X509KeyStorageFlags.Exportable);
}
return certificate;
}
当我生成证书,将其存储并使用时,一切正常,但是如果证书已经存在,我将对其进行检索以使用它。
这是我找回它的方式:
public static X509Certificate2 GetOrCreateCertificate(string serverName, string applicationUri)
{
using (X509Store store = new X509Store(OPC_UA_STORE_NAME, StoreLocation.LocalMachine))
{
X509Certificate2 certificate;
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, serverName, true);
if (certificateCollection.Count > 0)
{
certificate = certificateCollection[0];
_logger.Information("Using certificate " + serverName + " found in the store: " + certificate + ". Valid: " + (certificate.Verify() ? "True" : "False"));
return certificate;
}
certificate = GenerateCertificate(serverName, applicationUri);
_logger.Information("No valid certificate found for " + serverName + ". Building a new one: " + certificate);
store.Add(certificate);
using (X509Store rootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
{
using (X509Certificate2 withoutPrivateKey = new X509Certificate2(certificate.RawData))
{
rootStore.Open(OpenFlags.ReadWrite);
rootStore.Add(withoutPrivateKey);
}
}
return certificate;
}
}
在这种情况下,我得到一个错误:
然后我的OPC UA服务器在网络上无效(我想是出于相同的原因,但没有证明)。
知道我为什么要获得这个MS Event吗?