C# - Bouncy Castle - How to Create Child Certificate using Root Certificate?

Viewed 33

I have generated a Root certificate using PowerShell command

New-SelfSignedCertificate -DnsName "localhost", "localhost" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(10) -FriendlyName "CAlocalhost" -KeyUsageProperty All -KeyUsage CertSign, CRLSign, DigitalSignature.

I am also able to generate Child certificate using PowerShell command but not able to find a way to do so.

$rootcert = ( Get-ChildItem -Path cert:\LocalMachine\My\634EB82AF9DF2889EF0003ABA15506CBED380A41 )

New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname "localhost" -Signer $rootcert -NotAfter (Get-Date).AddYears(10) -FriendlyName "Clientlocalhost"

Issues:

  1. How to read pfx file using Bouncy Castle library. Currently I have used Microsoft one to achieve this?
  2. How to get private key from pfx file or specifically AsymmetricKeyParameter object?
  3. How to add child private key to certificate once signed with Root certificate?

Existing code:

public static Org.BouncyCastle.X509.X509Certificate GenerateCertificate22()
{
    // How to read pfx file using Bouncy Castle library. Currently I have used Microsoft one to achieve this?
    Org.BouncyCastle.X509.X509Certificate caCertificate
        = new Org.BouncyCastle.X509.X509Certificate(new
        System.Security.Cryptography.X509Certificates.X509Certificate2(Path.Combine(Path.GetDirectoryName(Assembly
        .GetExecutingAssembly().Location), "RootCertificate.pfx"), "Server123",
        System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet |
        System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet |
        System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable)
        .Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));

    BigInteger bigInteger = BigInteger.ProbablePrime(120, new Random());
    X509Name subjectName = new X509Name("Child Certificate");
    X509Name issuerName = new X509Name(caCertificate.SubjectDN.ToString());

    RsaKeyPairGenerator childCertificateRSAKeyPairGenerator = new RsaKeyPairGenerator();
    childCertificateRSAKeyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
    AsymmetricCipherKeyPair childCertificateRSAKeyPair = childCertificateRSAKeyPairGenerator.GenerateKeyPair();
    string signatureAlgorithm = "SHA256WithRSA";
    PrivateKeyInfo childPrivateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(childCertificateRSAKeyPair.Private);

    X509V3CertificateGenerator childCertificateGenerator = new X509V3CertificateGenerator();
    childCertificateGenerator.SetSerialNumber(bigInteger);
    childCertificateGenerator.SetSubjectDN(subjectName);
    childCertificateGenerator.SetIssuerDN(issuerName);
    childCertificateGenerator.SetNotAfter(DateTime.UtcNow.AddMonths(10));
    childCertificateGenerator.SetNotBefore(DateTime.UtcNow);
    childCertificateGenerator.SetPublicKey(childCertificateRSAKeyPair.Public);

    //How to get private key from pfx file or specifically AsymmetricKeyParameter object or caCertificate's PrivateKey?
    ISignatureFactory signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, caCertificate.PrivateKey,
        new SecureRandom(new CryptoApiRandomGenerator()));

    Org.BouncyCastle.X509.X509Certificate x509Certificate = childCertificateGenerator.Generate(signatureFactory);

    // How to add child private key(childPrivateKey) to certificate once signed with Root certificate?

    return x509Certificate;
}
0 Answers
Related