<pre>using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using Org.BouncyCastle.Asn1.Microsoft;
namespace csrextension
{
class Program
{
static void Main(string[] args)
{
AsymmetricCipherKeyPair pair;
Pkcs10CertificationRequest csr;
var ecMode = true;
var values = new Dictionary<DerObjectIdentifier, string> {
{X509Name.CN, ""},
{X509Name.OU, "Domain Control Validated"},
{X509Name.O, ""},
{X509Name.L, "London"},
{X509Name.ST, "England"},
{X509Name.C, "GB"},
};
var subjectAlternateNames = new GeneralName[] { };
string certificateTemplateName = "ZATCA-Code-Signing";
X509ExtensionsGenerator extensionsGenerator = new X509ExtensionsGenerator();
var micro = new Dictionary<MicrosoftObjectIdentifiers, DerObjectIdentifier>();
var extensions = new Dictionary<DerObjectIdentifier, X509Extension>()
{
{X509Extensions.BasicConstraints, new X509Extension(true, new DerOctetString(new BasicConstraints(false)))},
{X509Extensions.KeyUsage, new X509Extension(true, new DerOctetString(new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment | KeyUsage.DataEncipherment | KeyUsage.NonRepudiation)))},
{X509Extensions.ExtendedKeyUsage, new X509Extension(false, new DerOctetString(new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)))},
};
if (values[X509Name.CN].StartsWith("www.")) values[X509Name.CN] = values[X509Name.CN].Substring(4);
if (!values[X509Name.CN].StartsWith("*.") && subjectAlternateNames.Length == 0)
subjectAlternateNames = new GeneralName[] { new GeneralName(GeneralName.DnsName, $"www.{values[X509Name.CN]}") };
if (subjectAlternateNames.Length > 0)
extensions.Add(X509Extensions.SubjectAlternativeName, new X509Extension(false, new DerOctetString(new GeneralNames(subjectAlternateNames))));
micro.Add(MicrosoftObjectIdentifiers.MicrosoftCertTemplateV1, false, (Asn1OctetString)new DerOctetString((Asn1Encodable)new DisplayText(2, certificateTemplateName)));
var subject = new X509Name(values.Keys.Reverse().ToList(), values);
if (ecMode)
{
var gen = new ECKeyPairGenerator();
var ecp = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
gen.Init(new ECKeyGenerationParameters(new ECDomainParameters(ecp.Curve, ecp.G, ecp.N, ecp.H, ecp.GetSeed()), new SecureRandom()));
pair = gen.GenerateKeyPair();
csr = new Pkcs10CertificationRequest("SHA256withECDSA", subject, pair.Public, new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new X509Extensions(extensions)))), pair.Private);
}
else
{
var gen = new RsaKeyPairGenerator();
gen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
pair = gen.GenerateKeyPair();
extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(false, new DerOctetString(new SubjectKeyIdentifierStructure(pair.Public))));
csr = new Pkcs10CertificationRequest("SHA256withRSA", subject, pair.Public, new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new X509Extensions(extensions)))), pair.Private);
}
var csrPem = new StringBuilder();
var csrPemWriter = new PemWriter(new StringWriter(csrPem));
csrPemWriter.WriteObject(csr);
csrPemWriter.Writer.Flush();
Console.WriteLine(csrPem.ToString());
var privateKeyPem = new StringBuilder();
var privateKeyPemWriter = new PemWriter(new StringWriter(privateKeyPem));
privateKeyPemWriter.WriteObject(pair.Private);
csrPemWriter.Writer.Flush();
}
}
}
What I have tried:
Hello,
I have this code to generate CSR ECDSA and want to add SANs, I can Add with GeneralName but don’t know how to add SerialNumber, Title, UID, registeredAddress, businessCategory and MicrosoftCertTemplateV1
Any help please?