Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is what I do (I'm using DSA, but if you are using RSA, just change the key generation).</p> <pre><code>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(); #region build certificate var certGen = new X509V3CertificateGenerator(); // build name attributes var nameOids = new ArrayList(); nameOids.Add(Org.BouncyCastle.Asn1.X509.X509Name.CN); nameOids.Add(X509Name.O); nameOids.Add(X509Name.C); var nameValues = new ArrayList(); nameValues.Add(friendlyName); nameValues.Add(subjectName); nameValues.Add(country); var subjectDN = new X509Name(nameOids, nameValues); // certificate fields certGen.SetSerialNumber(BigInteger.ValueOf(1)); certGen.SetIssuerDN(caCert.SubjectDN); certGen.SetNotBefore(validStartDate); certGen.SetNotAfter(validEndDate); certGen.SetSubjectDN(subjectDN); certGen.SetPublicKey(keys.Public); certGen.SetSignatureAlgorithm("SHA1withDSA"); // extended information certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert.GetPublicKey())); certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keys.Public)); #endregion // generate x509 certificate var cert = certGen.Generate(caPrivateKey); //ert.Verify(caCert.GetPublicKey()); var chain = new Dictionary&lt;string, Org.BouncyCastle.X509.X509Certificate&gt;(); //chain.Add("CertiFirmas CA", caCert); var caCn = caCert.SubjectDN.GetValues(X509Name.CN)[0].ToString(); chain.Add(caCn, caCert); // store the file return GeneratePkcs12(keys, cert, friendlyName, password, chain); } private static byte[] GeneratePkcs12(AsymmetricCipherKeyPair keys, Org.BouncyCastle.X509.X509Certificate cert, string friendlyName, string password, Dictionary&lt;string, Org.BouncyCastle.X509.X509Certificate&gt; chain) { var chainCerts = new List&lt;X509CertificateEntry&gt;(); // Create the PKCS12 store Pkcs12Store store = new Pkcs12StoreBuilder().Build(); // Add a Certificate entry X509CertificateEntry certEntry = new X509CertificateEntry(cert); store.SetCertificateEntry(friendlyName, certEntry); // use DN as the Alias. //chainCerts.Add(certEntry); // Add chain entries var additionalCertsAsBytes = new List&lt;byte[]&gt;(); if (chain != null &amp;&amp; chain.Count &gt; 0) { foreach (var additionalCert in chain) { additionalCertsAsBytes.Add(additionalCert.Value.GetEncoded()); } } if (chain != null &amp;&amp; chain.Count &gt; 0) { var addicionalCertsAsX09Chain = BuildCertificateChainBC(cert.GetEncoded(), additionalCertsAsBytes); foreach (var addCertAsX09 in addicionalCertsAsX09Chain) { chainCerts.Add(new X509CertificateEntry(addCertAsX09)); } } // Add a key entry AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private); // no chain store.SetKeyEntry(friendlyName, keyEntry, new X509CertificateEntry[] { certEntry }); using (var memoryStream = new MemoryStream()) { store.Save(memoryStream, password.ToCharArray(), new SecureRandom()); return memoryStream.ToArray(); } } </code></pre> <p>Some missing methods:</p> <pre><code>static IEnumerable&lt;Org.BouncyCastle.X509.X509Certificate&gt; BuildCertificateChainBC(byte[] primary, IEnumerable&lt;byte[]&gt; additional) { X509CertificateParser parser = new X509CertificateParser(); PkixCertPathBuilder builder = new PkixCertPathBuilder(); // Separate root from itermediate var intermediateCerts = new List&lt;Org.BouncyCastle.X509.X509Certificate&gt;(); 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&lt;Org.BouncyCastle.X509.X509Certificate&gt;(); } private static AsymmetricCipherKeyPair GenerateDsaKeys() { DSACryptoServiceProvider DSA = new DSACryptoServiceProvider(); var dsaParams = DSA.ExportParameters(true); AsymmetricCipherKeyPair keys = DotNetUtilities.GetDsaKeyPair(dsaParams); return keys; } </code></pre> <p>Also: you have to install you CA certificate into the Trusted CAs store in the client machine, as well as the client certificate (it could be in the Personal or ThirdParty store).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload