private static X509Certificate GenerateCertificate(Org.BouncyCastle.Security.SecureRandom random, string subjectName, AsymmetricCipherKeyPair subjectKeyPair, BigInteger subjectSerialNumber, string[] subjectAlternativeNames, string issuerName, AsymmetricCipherKeyPair issuerKeyPair, BigInteger issuerSerialNumber, bool isCertificateAuthority, KeyPurposeID[] usages, int expiresIn) { var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.SetSerialNumber(subjectSerialNumber); // Set the signature algorithm. This is used to generate the thumbprint which is then signed // with the issuer's private key. We'll use SHA-256, which is (currently) considered fairly strong. const string signatureAlgorithm = "SHA256WithRSA"; certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); var issuerDN = new X509Name(issuerName); certificateGenerator.SetIssuerDN(issuerDN); // Note: The subject can be omitted if you specify a subject alternative name (SAN). var subjectDN = new X509Name(subjectName); certificateGenerator.SetSubjectDN(subjectDN); // Our certificate needs valid from/to values. var notBefore = DateTime.UtcNow.Date; var notAfter = notBefore.AddYears(expiresIn); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // The subject's public key goes in the certificate. certificateGenerator.SetPublicKey(subjectKeyPair.Public); certificateGenerator.AddAuthorityKeyIdentifier(issuerDN, issuerKeyPair, issuerSerialNumber); certificateGenerator.AddSubjectKeyIdentifier(subjectKeyPair); certificateGenerator.AddBasicConstraints(isCertificateAuthority); if (usages != null && usages.Any()) { certificateGenerator.AddExtendedKeyUsage(usages); } if (subjectAlternativeNames != null && subjectAlternativeNames.Any()) { certificateGenerator.AddSubjectAlternativeNames(subjectAlternativeNames); } // The certificate is signed with the issuer's private key. var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); return(certificate); }
/// <summary> /// Generates a self-signed certificate with a specified <paramref name="issuerName"/> and <paramref name="subjectName"/>. /// </summary> /// <param name="subjectName">The subject name of the self-signed certificate.</param> /// <param name="issuerName">The issuer name of the self-signed certificate.</param> /// <exception cref="ArgumentException">When the <paramref name="subjectName"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">When the <paramref name="issuerName"/> is <c>null</c>.</exception> public static X509Certificate2 CreateWithIssuerAndSubjectName(string issuerName, string subjectName) { Guard.NotNullOrWhitespace(subjectName, nameof(subjectName), "Subject name should not be blank"); Guard.NotNullOrWhitespace(issuerName, nameof(issuerName), "Issuer name should not be blank"); issuerName = issuerName.StartsWith("CN=") ? issuerName : "CN=" + issuerName; subjectName = subjectName.StartsWith("CN=") ? subjectName : "CN=" + subjectName; SecureRandom random = GetSecureRandom(); AsymmetricCipherKeyPair subjectKeyPair = GenerateKeyPair(random, 2048); BigInteger serialNumber = GenerateSerialNumber(random); using (X509Certificate2 issuerCert = GenerateCA(issuerName)) { AsymmetricCipherKeyPair issuerKeyPair = DotNetUtilities.GetKeyPair(issuerCert.PrivateKey); var issuerSerialNumber = new BigInteger(issuerCert.GetSerialNumber()); var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddIssuer(issuerName, issuerKeyPair, issuerSerialNumber); certificateGenerator.SetSubjectDN(new X509Name(subjectName)); certificateGenerator.SetNotBefore(DateTime.UtcNow.Date); certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(30)); certificateGenerator.SetPublicKey(subjectKeyPair.Public); certificateGenerator.SetSerialNumber(serialNumber); certificateGenerator.AddSubjectKeyIdentifier(subjectKeyPair); certificateGenerator.AddBasicConstraints(isCertificateAuthority: false); X509Certificate certificate = certificateGenerator.GenerateCertificateAsn1(issuerKeyPair, random); X509Certificate2 convertCertificate = ConvertCertificate(certificate, subjectKeyPair, random); return(convertCertificate); } }
private static X509Certificate2 GenerateCA(string subjectName) { SecureRandom random = GetSecureRandom(); AsymmetricCipherKeyPair subjectKeyPair = GenerateKeyPair(random, 2048); BigInteger serialNumber = GenerateSerialNumber(random); var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddIssuer(subjectName, subjectKeyPair, serialNumber); certificateGenerator.SetSubjectDN(new X509Name(subjectName)); certificateGenerator.SetNotBefore(DateTime.UtcNow.Date); certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(30)); certificateGenerator.SetPublicKey(subjectKeyPair.Public); certificateGenerator.SetSerialNumber(serialNumber); certificateGenerator.AddSubjectKeyIdentifier(subjectKeyPair); certificateGenerator.AddBasicConstraints(isCertificateAuthority: true); X509Certificate certificate = certificateGenerator.GenerateCertificateAsn1(subjectKeyPair, random); return(ConvertCertificate(certificate, subjectKeyPair, random)); }