This is what I do (I use DSA, but if you use RSA, just change the key generation).
public void IssueClientFromCA() { // get CA string caCn = "MyCA CommonName"; Stream caCertFile = File.OpenRead(string.Format(@"{0}\{1}", _certificatesDir, "MyCAFile.pfx")); char[] caPass = "passwordForThePfx".ToCharArray(); Pkcs12Store store = new Pkcs12StoreBuilder().Build(); store.Load(caCertFile, caPass); var caCert = store.GetCertificate(caCn).Certificate; var caPrivKey = store.GetKey(caCn).Key; var clientCert = CertIssuer.GenerateDsaCertificateAsPkcs12( "My Client FriendlyName", "My Client SubjectName", "GT", new DateTime(2011,9,19), new DateTime(2014,9,18), "PFXPASS", caCert, caPrivKey); var saveAS = string.Format(@"{0}\{1}", _certificatesDir, "clientCertFile.pfx"); File.WriteAllBytes(saveAS, clientCert); } public static byte[] GenerateDsaCertificateAsPkcs12( string friendlyName, string subjectName, string country, DateTime validStartDate, DateTime validEndDate, string password, Org.BouncyCastle.X509.X509Certificate caCert, AsymmetricKeyParameter caPrivateKey) { var keys = GenerateDsaKeys();
Some missing methods:
static IEnumerable<Org.BouncyCastle.X509.X509Certificate> BuildCertificateChainBC(byte[] primary, IEnumerable<byte[]> additional) { X509CertificateParser parser = new X509CertificateParser(); PkixCertPathBuilder builder = new PkixCertPathBuilder(); // Separate root from itermediate var intermediateCerts = new List<Org.BouncyCastle.X509.X509Certificate>(); HashSet rootCerts = new HashSet(); foreach (byte[] cert in additional) { var x509Cert = parser.ReadCertificate(cert); // Separate root and subordinate certificates if (x509Cert.IssuerDN.Equivalent(x509Cert.SubjectDN)) rootCerts.Add(new TrustAnchor(x509Cert, null)); else intermediateCerts.Add(x509Cert); } // Create chain for this certificate X509CertStoreSelector holder = new X509CertStoreSelector(); holder.Certificate = parser.ReadCertificate(primary); // WITHOUT THIS LINE BUILDER CANNOT BEGIN BUILDING THE CHAIN intermediateCerts.Add(holder.Certificate); PkixBuilderParameters builderParams = new PkixBuilderParameters(rootCerts, holder); builderParams.IsRevocationEnabled = false; X509CollectionStoreParameters intermediateStoreParameters = new X509CollectionStoreParameters(intermediateCerts); builderParams.AddStore(X509StoreFactory.Create( "Certificate/Collection", intermediateStoreParameters)); PkixCertPathBuilderResult result = builder.Build(builderParams); return result.CertPath.Certificates.Cast<Org.BouncyCastle.X509.X509Certificate>(); } private static AsymmetricCipherKeyPair GenerateDsaKeys() { DSACryptoServiceProvider DSA = new DSACryptoServiceProvider(); var dsaParams = DSA.ExportParameters(true); AsymmetricCipherKeyPair keys = DotNetUtilities.GetDsaKeyPair(dsaParams); return keys; }
Also: you need to install the CA certificate in the trusted CA storage on the client computer, as well as the client certificate (it can be in the Personal or ThirdParty storage).
source share