예제 #1
0
        /// <summary>
        /// Builds the PFX with specified friendly name.
        /// </summary>
        /// <param name="friendlyName">The friendly name.</param>
        /// <param name="password">The password.</param>
        /// <returns>The PFX data.</returns>
        public byte[] Build(string friendlyName, string password)
        {
            var keyPair = LoadKeyPair();
            var store   = new Pkcs12StoreBuilder().Build();

            var entry = new X509CertificateEntry(certificate);

            store.SetCertificateEntry(friendlyName, entry);

            if (FullChain && !certificate.IssuerDN.Equivalent(certificate.SubjectDN))
            {
                var certChain        = FindIssuers();
                var certChainEntries = certChain.Select(c => new X509CertificateEntry(c)).ToList();
                certChainEntries.Add(entry);

                store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(keyPair.Private), certChainEntries.ToArray());
            }
            else
            {
                store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(keyPair.Private), new[] { entry });
            }

            using (var buffer = new MemoryStream())
            {
                store.Save(buffer, password.ToCharArray(), new SecureRandom());
                return(buffer.ToArray());
            }
        }
예제 #2
0
        public void Save(PFXSaveConfig config, string newCertificate)
        {
            TextReader sr        = new StringReader(newCertificate);
            PemReader  pemReader = new PemReader(sr);


            Pkcs12Store   store     = new Pkcs12StoreBuilder().Build();
            List <object> pemChains = new List <object>();

            object o;

            while ((o = pemReader.ReadObject()) != null)
            {
                pemChains.Add(o);
            }

            X509CertificateEntry[]  chain   = pemChains.OfType <X509Certificate>().Select(c => new X509CertificateEntry(c)).ToArray();
            AsymmetricCipherKeyPair privKey = pemChains.OfType <AsymmetricCipherKeyPair>().FirstOrDefault();

            store.SetKeyEntry(config.Alias, new AsymmetricKeyEntry(privKey.Private), chain);
            FileStream p12file = File.Create(config.Path);

            store.Save(p12file, config.Password.ToCharArray(), new SecureRandom());
            p12file.Close();
        }
예제 #3
0
        internal void ReplaceServerCertificateAssignmentTest(ParametersValidation validationRequest, out StepType stepType, out SoapException exc, out int timeout)
        {
            int special;

            VoidCommand("ReplaceServerCertificateAssignment", ReplaceServerCertificateAssignment, validationRequest, true, out stepType, out exc, out timeout, out special);
            if (1 == special)
            {
                HTTPSServer.getInstance(true).Run(new X509Certificate2(m_UploadPKCS12), 1000);
            }
            if (2 == special)
            {
                HTTPSServer.getInstance(true).Run(new X509Certificate2(TestCommon.ReadBinary(TestCommon.TLSCertificate1Uri), "1234"), 1000);
            }
            if (3 == special)
            {
                HTTPSServer.getInstance(true).Run(new X509Certificate2(m_X509CertificateFromGet), 1000);
            }
            if (4 == special)
            {
                var keyStore = new Pkcs12StoreBuilder().SetUseDerEncoding(true).Build();
                keyStore.SetKeyEntry("KeyAlias",
                                     new AsymmetricKeyEntry(m_RSAKeyPair.Private),
                                     new[] { new X509CertificateEntry(m_X509CertificateSS) });
                using (var stream = new MemoryStream())
                {
                    keyStore.Save(stream, "".ToCharArray(), new SecureRandom());

                    HTTPSServer.getInstance(true).Run(new X509Certificate2(stream.ToArray(), ""), 1000);
                }
            }
            if (-1 == special)
            {
                HTTPSServer.getInstance(true).Run(new X509Certificate2(m_UploadPKCS12), -1);
            }
        }
예제 #4
0
        static byte[] GetPfxCertificateByteArray(ref string certString, ref string privateKey)
        {
            byte[] certArray       = Convert.FromBase64String(certString);
            byte[] privateKeyArray = Convert.FromBase64String(privateKey);


            //Translate to Pkcs#12
            var store = new Pkcs12StoreBuilder().Build();

            Org.BouncyCastle.X509.X509Certificate certTranslate = new X509CertificateParser().ReadCertificate(certArray);

            var certEntry = new X509CertificateEntry(certTranslate);
            var pk        = PrivateKeyFactory.CreateKey(privateKeyArray);
            var keyEntry  = new AsymmetricKeyEntry(pk);

            store.SetKeyEntry("", keyEntry, new X509CertificateEntry[] { certEntry });


            MemoryStream stream = new MemoryStream();

            store.Save(stream, new char[] { }, new SecureRandom());

            stream.Dispose();
            //FromString
            byte[] pfxByteArray = stream.ToArray();

            return(pfxByteArray);
        }
예제 #5
0
 /// <summary>
 /// Generate Pkcs#12 certificate.
 /// </summary>
 /// <param name="privateKey">Asymmetric private key.</param>
 /// <param name="privateKeyAlias">The alias of private key.</param>
 /// <param name="namedCerts">Certificate collection with alias set.</param>
 /// <param name="password">Password.</param>
 /// <returns></returns>
 /// <exception cref="Exception"/>
 public static Pkcs12Store GeneratePkcs12(AsymmetricKeyParameter privateKey,
                                          string privateKeyAlias,
                                          Dictionary <string, X509Certificate> namedCerts,
                                          string password)
 {
     if (privateKey is null)
     {
         throw new ArgumentNullException(nameof(privateKey));
     }
     if (privateKeyAlias is null)
     {
         throw new ArgumentNullException(nameof(privateKeyAlias));
     }
     if (namedCerts is null)
     {
         throw new ArgumentNullException(nameof(namedCerts));
     }
     using (MemoryStream ms = new MemoryStream())
     {
         Pkcs12Store store = new Pkcs12StoreBuilder().Build();
         List <X509CertificateEntry> certEntries = new List <X509CertificateEntry>();
         foreach (KeyValuePair <string, X509Certificate> namedCert in namedCerts)
         {
             X509CertificateEntry certEntry = new X509CertificateEntry(namedCert.Value);
             store.SetCertificateEntry(namedCert.Key, certEntry);
             certEntries.Add(certEntry);
         }
         store.SetKeyEntry(privateKeyAlias, new AsymmetricKeyEntry(privateKey), certEntries.ToArray());
         char[] pass = string.IsNullOrWhiteSpace(password) ? null : password.ToCharArray();
         store.Save(ms, pass, Common.ThreadSecureRandom.Value);
         ms.Flush();
         return(new Pkcs12Store(ms, pass));
     }
 }
예제 #6
0
        private static void Teste(AsymmetricCipherKeyPair keys)
        {
            string certSubjectName = "UShadow_RSA";
            var    certName        = new X509Name("CN=" + certSubjectName);
            var    serialNo        = Org.BouncyCastle.Math.BigInteger.ProbablePrime(120, new Random());


            X509V3CertificateGenerator gen2 = new X509V3CertificateGenerator();

            gen2.SetSerialNumber(serialNo);
            gen2.SetSubjectDN(certName);
            gen2.SetIssuerDN(new X509Name(true, "CN=UShadow"));
            gen2.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0)));
            gen2.SetNotAfter(DateTime.Now.AddYears(2));
            gen2.SetSignatureAlgorithm("sha256WithRSA");

            gen2.SetPublicKey(keys.Public);

            Org.BouncyCastle.X509.X509Certificate newCert = gen2.Generate(keys.Private);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry certEntry = new X509CertificateEntry(newCert);

            store.SetCertificateEntry(newCert.SubjectDN.ToString(), certEntry);

            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private);

            store.SetKeyEntry(newCert.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { certEntry });
        }
        private static void SavePkcs12Certificate(CertificateChainWithPrivateKey certChainWithKey, string?password,
                                                  string certFilePath, bool chain)
        {
            if (File.Exists(certFilePath))
            {
                throw new ArgumentException("Cert file already exists. Please remove it or switch directories.");
            }

            var store = new Pkcs12StoreBuilder().Build();

            // cert chain
            var chainLen = 1;

            if (chain)
            {
                chainLen = certChainWithKey.Certificates.Length;
            }

            for (var i = 0; i < chainLen; i++)
            {
                var cert      = certChainWithKey.Certificates[i];
                var certEntry = new X509CertificateEntry(cert);
                store.SetCertificateEntry(cert.SubjectDN.ToString(), certEntry);
            }

            // private key
            var primaryCert = certChainWithKey.PrimaryCertificate;
            var keyEntry    = new AsymmetricKeyEntry(certChainWithKey.PrivateKey);

            store.SetKeyEntry(primaryCert.SubjectDN.ToString(), keyEntry,
                              new[] { new X509CertificateEntry(primaryCert) });

            using var stream = File.OpenWrite(certFilePath);
            store.Save(stream, password?.ToCharArray(), new SecureRandom());
        }
예제 #8
0
        public static byte[] ExportPfx(byte[] pemCert, byte[] pemPrivateKey)
        {
            var parsedCert = new X509CertificateParser().ReadCertificate(pemCert);

            using var privateStream = new MemoryStream(pemPrivateKey);
            using var privateReader = new StreamReader(privateStream);
            var reader = new PemReader(privateReader);

            var keyPair = reader.ReadObject() as AsymmetricCipherKeyPair;

            if (keyPair == null)
            {
                throw new Exception("Could not read key pair from provided private key bytes");
            }

            var x509Name = new X509Name(parsedCert.SubjectDN.ToString());
            var alias    = (x509Name.GetValueList(X509Name.CN)?[0] ?? parsedCert.SubjectDN.ToString()) as string;

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry(alias, new AsymmetricKeyEntry(keyPair.Private), new[] { new X509CertificateEntry(parsedCert) });

            using var ms = new MemoryStream();
            store.Save(ms, new char[0], new SecureRandom());
            ms.Seek(0, SeekOrigin.Begin);

            return(ms.ToArray());
        }
예제 #9
0
        internal static (X509Certificate2, IEnumerable <X509Certificate2>) ParseCertificateAndKey(string certificateWithChain, string privateKey)
        {
            IEnumerable <string> pemCerts = ParsePemCerts(certificateWithChain);

            if (pemCerts.FirstOrDefault() == null)
            {
                throw new InvalidOperationException("Certificate is required");
            }

            IEnumerable <X509Certificate2> certsChain = GetCertificatesFromPem(pemCerts.Skip(1));

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            IList <X509CertificateEntry> chain = new List <X509CertificateEntry>();

            // note: the seperator between the certificate and private key is added for safety to delinate the cert and key boundary
            var sr        = new StringReader(pemCerts.First() + "\r\n" + privateKey);
            var pemReader = new PemReader(sr);

            AsymmetricKeyParameter keyParams = null;
            object certObject = pemReader.ReadObject();

            while (certObject != null)
            {
                if (certObject is X509Certificate x509Cert)
                {
                    chain.Add(new X509CertificateEntry(x509Cert));
                }

                // when processing certificates generated via openssl certObject type is of AsymmetricCipherKeyPair
                if (certObject is AsymmetricCipherKeyPair keyPair)
                {
                    certObject = keyPair.Private;
                }

                if (certObject is RsaPrivateCrtKeyParameters rsaParameters)
                {
                    keyParams = rsaParameters;
                }
                else if (certObject is ECPrivateKeyParameters ecParameters)
                {
                    keyParams = ecParameters;
                }

                certObject = pemReader.ReadObject();
            }

            if (keyParams == null)
            {
                throw new InvalidOperationException("Private key is required");
            }

            store.SetKeyEntry("Edge", new AsymmetricKeyEntry(keyParams), chain.ToArray());
            using (var p12File = new MemoryStream())
            {
                store.Save(p12File, new char[] { }, new SecureRandom());

                var cert = new X509Certificate2(p12File.ToArray());
                return(cert, certsChain);
            }
        }
        public static void CreatePfxFile(
            IReadOnlyList <X509Certificate> certChain,
            AsymmetricKeyParameter privateKey,
            string unsecurePassword,
            Stream output)
        {
            new { certChain }.Must().NotBeNullNorEmptyEnumerableNorContainAnyNulls();
            new { privateKey }.Must().NotBeNull();
            new { privateKey.IsPrivate }.Must().BeTrue();
            new { unsecurePassword }.Must().NotBeNullNorWhiteSpace();
            new { output }.Must().NotBeNull();
            new { output.CanWrite }.Must().BeTrue();

            certChain = certChain.OrderCertChainFromLowestToHighestLevelOfTrust();

            var store       = new Pkcs12StoreBuilder().Build();
            var certEntries = new List <X509CertificateEntry>();

            foreach (var cert in certChain)
            {
                var certEntry = new X509CertificateEntry(cert);
                certEntries.Add(certEntry);
                var certSubjectAttributes = cert.GetX509SubjectAttributes();
                var certStoreKey          = certSubjectAttributes[X509SubjectAttributeKind.CommonName];
                store.SetCertificateEntry(certStoreKey, certEntry);
            }

            var keyEntry  = new AsymmetricKeyEntry(privateKey);
            var firstCert = certChain.First();
            var firstCertSubjectAttributes = firstCert.GetX509SubjectAttributes();

            store.SetKeyEntry(firstCertSubjectAttributes[X509SubjectAttributeKind.CommonName], keyEntry, certEntries.ToArray());
            store.Save(output, unsecurePassword.ToCharArray(), new SecureRandom());
        }
예제 #11
0
        /// <summary>
        /// Generates pfx from client configuration
        /// </summary>
        /// <param name="config">Kuberentes Client Configuration</param>
        /// <returns>Generated Pfx Path</returns>
        public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
        {
            byte[] keyData  = null;
            byte[] certData = null;

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData))
            {
                keyData = Convert.FromBase64String(config.ClientCertificateKeyData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientKeyFilePath))
            {
                keyData = File.ReadAllBytes(config.ClientKeyFilePath);
            }

            if (keyData == null)
            {
                throw new KubeConfigException("certData is empty");
            }

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
            {
                certData = Convert.FromBase64String(config.ClientCertificateData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath))
            {
                certData = File.ReadAllBytes(config.ClientCertificateFilePath);
            }

            if (certData == null)
            {
                throw new KubeConfigException("certData is empty");
            }

            var cert = new X509CertificateParser().ReadCertificate(new MemoryStream(certData));

            object obj;

            using (var reader = new StreamReader(new MemoryStream(keyData)))
            {
                obj = new PemReader(reader).ReadObject();
                var key = obj as AsymmetricCipherKeyPair;
                if (key != null)
                {
                    var cipherKey = key;
                    obj = cipherKey.Private;
                }
            }

            var rsaKeyParams = (RsaPrivateCrtKeyParameters)obj;

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(rsaKeyParams), new[] { new X509CertificateEntry(cert) });

            using (var pkcs = new MemoryStream())
            {
                store.Save(pkcs, new char[0], new SecureRandom());
                return(new X509Certificate2(pkcs.ToArray()));
            }
        }
예제 #12
0
        public PKCS12KeyStore(string keyAlias, RSAKeyPair keyPair, X509CertificateBase certificate)
        {
            m_KeyStore = new Pkcs12StoreBuilder().SetUseDerEncoding(true).Build();

            m_KeyStore.SetKeyEntry(keyAlias,
                                   new AsymmetricKeyEntry(PrivateKeyFactory.CreateKey(keyPair.PrivateKey)),
                                   new[] { new X509CertificateEntry(new X509CertificateParser().ReadCertificate(certificate.GetEncoded())) });
        }
예제 #13
0
        /// <summary>
        ///     Build a PFX (PKCS12) store containing the specified certificate and private key.
        /// </summary>
        /// <param name="certificatePem">
        ///     A PEM block containing the certificate data.
        /// </param>
        /// <param name="keyPem">
        ///     A PEM block containing the private key data.
        /// </param>
        /// <param name="password">
        ///     The password to use for protecting the exported data.
        /// </param>
        /// <returns>
        ///     A byte array containing the exported data.
        /// </returns>
        public static byte[] BuildPfx(string certificatePem, string keyPem, string password)
        {
            if (String.IsNullOrWhiteSpace(certificatePem))
            {
                throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'certificateData'.", nameof(certificatePem));
            }

            if (String.IsNullOrWhiteSpace(keyPem))
            {
                throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'keyData'.", nameof(keyPem));
            }

            if (String.IsNullOrWhiteSpace(password))
            {
                throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'password'.", nameof(password));
            }

            List <X509CertificateEntry> chain      = new List <X509CertificateEntry>();
            AsymmetricCipherKeyPair     privateKey = null;

            foreach (object pemObject in EnumeratePemObjects(password, certificatePem, keyPem))
            {
                if (pemObject is BCX509Certificate certificate)
                {
                    chain.Add(new X509CertificateEntry(certificate));
                }
                else if (pemObject is AsymmetricCipherKeyPair keyPair)
                {
                    privateKey = keyPair;
                }
            }

            if (chain.Count == 0)
            {
                throw new CryptographicException("Cannot find X.509 certificate in PEM data.");
            }

            if (privateKey == null)
            {
                throw new CryptographicException("Cannot find private key in PEM data.");
            }

            string certificateSubject = chain[0].Certificate.SubjectDN.ToString();

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry(certificateSubject, new AsymmetricKeyEntry(privateKey.Private), chain.ToArray());

            using (MemoryStream pfxData = new MemoryStream())
            {
                store.Save(pfxData, password.ToCharArray(), new SecureRandom());

                return(pfxData.ToArray());
            }
        }
예제 #14
0
        private static byte[] GeneratePkcs12(
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keys,
            Org.BouncyCastle.X509.X509Certificate cert,
            string friendlyName,
            string password,
            System.Collections.Generic.Dictionary <string, Org.BouncyCastle.X509.X509Certificate> chain)
        {
            System.Collections.Generic.List <X509CertificateEntry> chainCerts =
                new System.Collections.Generic.List <X509CertificateEntry>();

            // 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
            System.Collections.Generic.List <byte[]> additionalCertsAsBytes =
                new System.Collections.Generic.List <byte[]>();
            if (chain != null && chain.Count > 0)
            {
                foreach (System.Collections.Generic.KeyValuePair <string, X509Certificate> additionalCert in chain)
                {
                    additionalCertsAsBytes.Add(additionalCert.Value.GetEncoded());
                }
            }

            if (chain != null && chain.Count > 0)
            {
                System.Collections.Generic.IEnumerable <X509Certificate> addicionalCertsAsX09Chain =
                    BuildCertificateChainBC(cert.GetEncoded(), additionalCertsAsBytes);

                foreach (X509Certificate 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 (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
            {
                store.Save(memoryStream, password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
                return(memoryStream.ToArray());
            }
        }
예제 #15
0
        public static Certificate GenerateCertificate(string subject)
        {
            var result = new Certificate();
            var random = new SecureRandom();
            var certificateGenerator = new X509V3CertificateGenerator();

            var serialNumber =
                BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            certificateGenerator.SetIssuerDN(new X509Name($"C=NL, O=SomeCompany, CN={subject}"));
            certificateGenerator.SetSubjectDN(new X509Name($"C=NL, O=SomeCompany, CN={subject}"));
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(1));

            const int strength = 2048;
            var       keyGenerationParameters = new KeyGenerationParameters(random, strength);
            var       keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            result.PrivateKeyPem = GetPrivateKey(subjectKeyPair);
            result.PublicKeyPem  = GetPublicKey(subjectKeyPair);

            var          issuerKeyPair      = subjectKeyPair;
            const string signatureAlgorithm = "SHA256WithRSA";
            var          signatureFactory   = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private);
            var          bouncyCert         = certificateGenerator.Generate(signatureFactory);

            // Lets convert it to X509Certificate2
            X509Certificate2 certificate;

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry($"{subject}_key", new AsymmetricKeyEntry(subjectKeyPair.Private),
                              new[] { new X509CertificateEntry(bouncyCert) });
            string exportpw = "micah123";

            using (var ms = new System.IO.MemoryStream())
            {
                store.Save(ms, exportpw.ToCharArray(), random);
                certificate = new X509Certificate2(ms.ToArray(), exportpw, X509KeyStorageFlags.Exportable);
            }

            //Console.WriteLine($"Generated cert with thumbprint {certificate.Thumbprint}");
            result.Result = certificate;
            return(result);
        }
예제 #16
0
//
//        public static RSA Get2(string privateKey)
//        {
//
//            PemReader reader = new PemReader(new StringReader(privateKey));
//            var parms = reader.ReadObject() as AsymmetricCipherKeyPair;
//
//            var result = RSA.Create(DotNetUtilities.ToRSAParameters(parms));
//            result.ImportParameters(parms.Private);
//        }

        public static X509Certificate2 Get(string privateKey, string publicKey, string subject)
        {
            PemReader reader       = new PemReader(new StringReader(privateKey));
            PemReader readerPublic = new PemReader(new StringReader(publicKey));
            var       result       = reader.ReadObject() as AsymmetricCipherKeyPair;
            var       pubKey       = readerPublic.ReadObject() as RsaKeyParameters;

            if (GetPublicKey(result) != publicKey)
            {
                throw new Exception("Public key doesnt match private key");
            }

            var          certificateGenerator = new X509V3CertificateGenerator();
            const string signatureAlgorithm   = "SHA256WithRSA";

            certificateGenerator.SetPublicKey(result.Public);
            certificateGenerator.SetSerialNumber(GetRandomSerialNumber());

            certificateGenerator.SetIssuerDN(new X509Name($"C=NL, O=SomeCompany, CN={subject}"));
            certificateGenerator.SetSubjectDN(new X509Name($"C=NL, O=SomeCompany, CN={subject}"));
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(1));


            var         signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, result.Private);
            var         bouncyCert       = certificateGenerator.Generate(signatureFactory);
            Pkcs12Store store            = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry($"{subject}_key", new AsymmetricKeyEntry(result.Private),
                              new[] { new X509CertificateEntry(bouncyCert) });
            string exportpw = "micah123";

            using (var ms = new System.IO.MemoryStream())
            {
                store.Save(ms, exportpw.ToCharArray(), new SecureRandom());
                return(new X509Certificate2(ms.ToArray(), exportpw, X509KeyStorageFlags.Exportable));
            }

//            var cert = new X509Certificate2();
//            cert.Import(result.Public);
            //return bouncyCert.AsX509Certificate2();
//            // Lets convert it to X509Certificate2
//            X509Certificate2 certificate;
//
//            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
//            store.SetKeyEntry($"{subject}_key",new AsymmetricKeyEntry(subjectKeyPair.Private), new [] {new X509CertificateEntry(bouncyCert)});
//            string exportpw = Guid.NewGuid().ToString("x");
//
//            using(var ms = new System.IO.MemoryStream()){
//                store.Save(ms,exportpw.ToCharArray(),random);
//                certificate = new X509Certificate2(ms.ToArray(),exportpw,X509KeyStorageFlags.Exportable);
//            }
        }
        public static void GenerateCertificate(GenerateCertificateOptions options)
        {
            //generate random numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            var keyGenerator = GeneratorUtilities.GetKeyPairGenerator(options.Algorithm);

            keyGenerator.Init(new KeyGenerationParameters(new SecureRandom(), options.KeyStrength));

            var keyPair = keyGenerator.GenerateKeyPair();

            //the certificate generator
            var certificateGenerator = new X509V3CertificateGenerator();

            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));

            //serial number
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            certificateGenerator.SetIssuerDN(options.Issuer);
            certificateGenerator.SetSubjectDN(options.Subject);

            //valid For
            certificateGenerator.SetNotBefore(options.NotBefore);
            certificateGenerator.SetNotAfter(options.NotAfter);

            certificateGenerator.SetPublicKey(keyPair.Public);

            ISignatureFactory signatureFactory = new Asn1SignatureFactory(options.SignatureAlgorithm, keyPair.Private);

            //certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            certificate.CheckValidity();        //检查当前日期是否在证书的有效期内
            certificate.Verify(keyPair.Public); //使用公钥验证证书的签名

            var certEntry = new X509CertificateEntry(certificate);
            var store     = new Pkcs12StoreBuilder().Build();

            store.SetCertificateEntry(options.FriendlyName, certEntry);   //设置证书
            var chain = new X509CertificateEntry[1];

            chain[0] = certEntry;
            store.SetKeyEntry(options.FriendlyName, new AsymmetricKeyEntry(keyPair.Private), chain);   //设置私钥
            using (var fs = File.Create(options.Path))
            {
                store.Save(fs, options.Password.ToCharArray(), new SecureRandom()); //保存
            }
        }
예제 #18
0
        /// <summary>
        /// Loads the X.509 certificate with private key.
        /// </summary>
        /// <param name="options">The options used to load the certificate.</param>
        /// <returns>The certificate.</returns>
        public static X509Certificate2?GetCertificate(this FtpOptions options)
        {
            if (string.IsNullOrEmpty(options.Ftps.Certificate))
            {
                return(null);
            }

            var cert = new X509Certificate2(options.Ftps.Certificate, options.Ftps.Password);

            if (cert.HasPrivateKey)
            {
                return(cert);
            }

            cert.Dispose();

            var certCollection = new X509Certificate2Collection();

            certCollection.Import(options.Ftps.Certificate, options.Ftps.Password, X509KeyStorageFlags.Exportable);

            var passwordFinder = string.IsNullOrEmpty(options.Ftps.Password)
                ? (IPasswordFinder?)null
                : new BcStaticPassword(options.Ftps.Password);

            AsymmetricKeyParameter keyParameter;

            using (var pkReader = File.OpenText(options.Ftps.PrivateKey))
            {
                keyParameter = (AsymmetricKeyParameter) new PemReader(pkReader, passwordFinder).ReadObject();
            }

            var store = new Pkcs12StoreBuilder()
                        .SetUseDerEncoding(true)
                        .Build();

            var chain = certCollection.Cast <X509Certificate2>()
                        .Select(DotNetUtilities.FromX509Certificate)
                        .Select(x => new X509CertificateEntry(x))
                        .ToArray();

            store.SetKeyEntry("0", new AsymmetricKeyEntry(keyParameter), chain);

            byte[] data;
            using (var output = new MemoryStream())
            {
                store.Save(output, Array.Empty <char>(), new SecureRandom());
                data = output.ToArray();
            }

            var result = Pkcs12Utilities.ConvertToDefiniteLength(data);

            return(new X509Certificate2(result));
        }
예제 #19
0
        private MSX509.X509Certificate2 CreateCertificate(X509Name name, X509Certificate certificate, AsymmetricKeyParameter privateKey)
        {
            var pkcs12Store = new Pkcs12StoreBuilder().Build();

            pkcs12Store.SetKeyEntry(GetFriendlyName(name), new AsymmetricKeyEntry(privateKey), new[] { new X509CertificateEntry(certificate) });
            var data = new MemoryStream();

            pkcs12Store.Save(data, pkcs12Password_.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));

            MSX509.X509KeyStorageFlags storage = MSX509.X509KeyStorageFlags.Exportable | MSX509.X509KeyStorageFlags.PersistKeySet |
                                                 ((store_ == MSX509.StoreLocation.LocalMachine) ? MSX509.X509KeyStorageFlags.MachineKeySet : MSX509.X509KeyStorageFlags.UserKeySet);

            return(new MSX509.X509Certificate2(data.ToArray(), pkcs12Password_, storage));
        }
예제 #20
0
        public static bool PemToPfx(Org.BouncyCastle.X509.X509Certificate cert, AsymmetricCipherKeyPair keyPair, string pfxFile)
        {
            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry[] chain = new X509CertificateEntry[1];
            chain[0] = new X509CertificateEntry(cert);
            store.SetKeyEntry("test", new AsymmetricKeyEntry(keyPair.Private), chain);
            FileStream p12file = File.Create(pfxFile);

            store.Save(p12file, null, new SecureRandom());
            p12file.Close();

            return(File.Exists(pfxFile));
        }
예제 #21
0
        public static X509Certificate2 GenerateCertificate(string subject, string companyName, string countryCode)
        {
            // https://gist.github.com/svrooij/ec6f664cd93cd09e84414112d23f6a42

            var random = new SecureRandom();
            var certificateGenerator = new X509V3CertificateGenerator();

            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            certificateGenerator.SetIssuerDN(new X509Name($"C={countryCode}, O={companyName}, CN={subject}"));
            certificateGenerator.SetSubjectDN(new X509Name($"C={countryCode}, O={companyName}, CN={subject}"));
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(999));

            const int strength = 2048;
            var       keyGenerationParameters = new KeyGenerationParameters(random, strength);
            var       keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            var          issuerKeyPair      = subjectKeyPair;
            const string signatureAlgorithm = "SHA256WithRSA";
            var          signatureFactory   = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private);
            var          bouncyCert         = certificateGenerator.Generate(signatureFactory);

            // Lets convert it to X509Certificate2
            X509Certificate2 certificate;

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry($"{subject}_key", new AsymmetricKeyEntry(subjectKeyPair.Private), new[] { new X509CertificateEntry(bouncyCert) });
            string exportpw = Guid.NewGuid().ToString("x");

            using (var ms = new System.IO.MemoryStream())
            {
                store.Save(ms, exportpw.ToCharArray(), random);
                certificate = new X509Certificate2(ms.ToArray(), exportpw, X509KeyStorageFlags.Exportable);
            }

#if DEBUG
            Console.WriteLine($"Generated cert with thumbprint {certificate.Thumbprint}");
#endif
            return(certificate);
        }
예제 #22
0
        /// <summary>
        /// Merges a certificate and private key into a single combined certificate
        /// </summary>
        public static X509Certificate2 CombineKeyAndCert(string CertificateFilename, string KeyFilename)
        {
            // Load the certificate
            string           CertificatePassword = "";
            X509Certificate2 Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            // Make sure we have a useful friendly name
            string FriendlyName = Cert.FriendlyName;

            if ((FriendlyName == "") || (FriendlyName == null))
            {
                FriendlyName = GetCommonNameFromCert(Cert);
            }

            // Create a PKCS#12 store with both the certificate and the private key in it
            Pkcs12Store Store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry[] CertChain = new X509CertificateEntry[1];
            Org.BouncyCastle.X509.X509Certificate BouncyCert = DotNetUtilities.FromX509Certificate(Cert);
            CertChain[0] = new X509CertificateEntry(BouncyCert);

            AsymmetricCipherKeyPair KeyPair = LoadKeyPairFromDiskBouncy(KeyFilename);

            Store.SetKeyEntry(FriendlyName, new AsymmetricKeyEntry(KeyPair.Private), CertChain);

            // Verify the public key from the key pair matches the certificate's public key
            AsymmetricKeyParameter CertPublicKey = BouncyCert.GetPublicKey();

            if (!(KeyPair.Public as RsaKeyParameters).Equals(CertPublicKey as RsaKeyParameters))
            {
                throw new InvalidDataException("The key pair provided does not match the certificate.  Make sure you provide the same key pair that was used to generate the original certificate signing request");
            }

            // Export the merged cert as a .p12
            string TempFileName = Path.GetTempFileName();

            string ReexportedPassword = "******";

            Stream OutStream = File.OpenWrite(TempFileName);

            Store.Save(OutStream, ReexportedPassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
            OutStream.Close();

            // Load it back in and delete the temporary file
            X509Certificate2 Result = new X509Certificate2(TempFileName, ReexportedPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

            FileOperations.DeleteFile(TempFileName);
            return(Result);
        }
        public X509Certificate2 GenerateCertificate()
        {
            var random = new SecureRandom();
            var certificateGenerator = new X509V3CertificateGenerator();

            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            var name = $"C={_config["Certificates:Country"]}," +
                       $"ST={_config["Certificates:State"]}," +
                       $"L={_config["Certificates:Locality"]}," +
                       $"O={_config["Certificates:Organization"]}";

            certificateGenerator.SetIssuerDN(new X509Name(name));
            certificateGenerator.SetSubjectDN(new X509Name(name));
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddMonths(1));

            const int strength = 2048;
            var       keyGenerationParameters = new KeyGenerationParameters(random, strength);
            var       keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            var          issuerKeyPair      = subjectKeyPair;
            const string signatureAlgorithm = "SHA256WithRSA";
            var          signatureFactory   = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private);
            var          bouncyCert         = certificateGenerator.Generate(signatureFactory);

            // Lets convert it to X509Certificate2
            X509Certificate2 certificate;

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry($"signing_key", new AsymmetricKeyEntry(subjectKeyPair.Private), new [] { new X509CertificateEntry(bouncyCert) });

            using (var ms = new System.IO.MemoryStream()){
                store.Save(ms, ConfigManager.Certificates.Password.ToCharArray(), random);
                certificate = new X509Certificate2(ms.ToArray(), ConfigManager.Certificates.Password, X509KeyStorageFlags.Exportable);
            }

            return(certificate);
        }
예제 #24
0
        internal static (X509Certificate2, IEnumerable <X509Certificate2>) ParseCertificateResponse(CertificateResponse response)
        {
            IEnumerable <string> pemCerts = ParsePemCerts(response.Certificate);

            if (pemCerts.FirstOrDefault() == null)
            {
                throw new InvalidOperationException("Certificate is required");
            }

            IEnumerable <X509Certificate2> certsChain = GetCertificatesFromPem(pemCerts.Skip(1));

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            IList <X509CertificateEntry> chain = new List <X509CertificateEntry>();

            var sr        = new StringReader(pemCerts.First() + "\r\n" + response.PrivateKey.Bytes);
            var pemReader = new PemReader(sr);

            RsaPrivateCrtKeyParameters keyParams = null;
            object certObject = pemReader.ReadObject();

            while (certObject != null)
            {
                if (certObject is Org.BouncyCastle.X509.X509Certificate x509Cert)
                {
                    chain.Add(new X509CertificateEntry(x509Cert));
                }
                if (certObject is RsaPrivateCrtKeyParameters)
                {
                    keyParams = ((RsaPrivateCrtKeyParameters)certObject);
                }

                certObject = pemReader.ReadObject();
            }

            if (keyParams == null)
            {
                throw new InvalidOperationException("Private key is required");
            }

            store.SetKeyEntry("Edge", new AsymmetricKeyEntry(keyParams), chain.ToArray());
            using (var p12File = new MemoryStream())
            {
                store.Save(p12File, new char[] { }, new SecureRandom());

                var cert = new X509Certificate2(p12File.ToArray());
                return(cert, certsChain);
            }
        }
예제 #25
0
        /// <summary>
        /// Generates the PFX client certificate.
        /// </summary>
        /// <param name="user">The config <see cref="User"/>.</param>
        /// <returns>The client certificate.</returns>
        public static X509Certificate2 GenerateClientCert(User user)
        {
            if (null == user)
            {
                throw new Exception(string.Format("Missing required parameter {0}.", nameof(user)));
            }

            byte[] clientCertData = default(byte[]);
            if (!KubeConfigUtils.TryGetDataFromBase64String(user.UserData.ClientCertificateData, out clientCertData))
            {
                throw new Exception(string.Format("Invalid base54 {0} string.", nameof(user.UserData.ClientCertificateData)));
            }

            byte[] clientKeyData = default(byte[]);
            if (!KubeConfigUtils.TryGetDataFromBase64String(user.UserData.ClientKeyData, out clientKeyData))
            {
                throw new Exception(string.Format("Invalid base64 {0} string.", nameof(user.UserData.ClientKeyData)));
            }

            // Generate RSA key
            object obj = default(object);

            using (StreamReader reader = new StreamReader(new MemoryStream(clientKeyData)))
            {
                obj = new PemReader(reader).ReadObject();
                var key = obj as AsymmetricCipherKeyPair;
                if (null != key)
                {
                    var cipherKey = key;
                    obj = cipherKey.Private;
                }
            }
            RsaPrivateCrtKeyParameters rsaPrivateKeyParams = (RsaPrivateCrtKeyParameters)obj;

            // Save cert entry in pkcs12 store
            Org.BouncyCastle.X509.X509Certificate clientCert = new X509CertificateParser().ReadCertificate(new MemoryStream(clientCertData));
            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(rsaPrivateKeyParams), new[] { new X509CertificateEntry(clientCert) });

            // Generate pfx
            using (MemoryStream pkcsStream = new MemoryStream())
            {
                store.Save(pkcsStream, new char[0], new SecureRandom());
                return(new X509Certificate2(pkcsStream.ToArray()));
            }
        }
예제 #26
0
        private void WritePfx(string certPem, string keyPem, string password, string filePath)
        {
            var cert      = ReadCertificate(certPem);
            var certEntry = new X509CertificateEntry(cert);
            var chain     = new X509CertificateEntry[] { certEntry };

            var privKey = ReadPrivateKey(keyPem);

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry("", new AsymmetricKeyEntry(privKey), chain);

            using (var p12file = File.Create(filePath))
            {
                store.Save(p12file, password.ToCharArray(), new SecureRandom());
            }
        }
        private static X509Certificate2 GenerateFromCertAndPriv()
        {
            X509CertificateEntry    entry   = null;
            AsymmetricCipherKeyPair privKey = null;

            using (Stream ms = File.OpenRead("Resources/keypair-signed.crt".Locate()))
            {
                PemReader pemReader = new PemReader(new StreamReader(ms));
                object    o;
                while ((o = pemReader.ReadObject()) != null)
                {
                    if (o is X509Certificate)
                    {
                        entry = new X509CertificateEntry((X509Certificate)o);
                    }
                }
            }

            using (Stream ms = File.OpenRead("Resources/keypair-signed.key".Locate()))
            {
                PemReader pemReader = new PemReader(new StreamReader(ms));
                object    o;
                while ((o = pemReader.ReadObject()) != null)
                {
                    if (o is AsymmetricCipherKeyPair)
                    {
                        privKey = (AsymmetricCipherKeyPair)o;
                    }
                }
            }

            if (entry != null && privKey != null)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    Pkcs12Store store = new Pkcs12StoreBuilder().Build();
                    store.SetKeyEntry("key2", new AsymmetricKeyEntry(privKey.Private), new[] { entry });
                    store.Save(ms, "123456".ToCharArray(), new SecureRandom());
                    ms.Flush();
                    ms.Position = 0;
                    return(new X509Certificate2(ms.ToArray(), "123456", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.EphemeralKeySet));
                }
            }

            return(null);
        }
예제 #28
0
        private void testNoExtraLocalKeyID(byte[] store1data)
        {
            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");

            kpg.Init(new RsaKeyGenerationParameters(
                         BigInteger.ValueOf(0x10001), new SecureRandom(), 512, 25));

            AsymmetricCipherKeyPair newPair = kpg.GenerateKeyPair();

            Pkcs12Store store1 = new Pkcs12StoreBuilder().Build();

            store1.Load(new MemoryStream(store1data, false), passwd);

            Pkcs12Store store2 = new Pkcs12StoreBuilder().Build();

            AsymmetricKeyEntry k1 = store1.GetKey("privatekey");

            X509CertificateEntry[] chain1 = store1.GetCertificateChain("privatekey");

            X509CertificateEntry[] chain2 = new X509CertificateEntry[chain1.Length + 1];

            Array.Copy(chain1, 0, chain2, 1, chain1.Length);

            chain2[0] = CreateCert(newPair.Public, k1.Key, "*****@*****.**", "*****@*****.**");

            if (chain1[0][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
            {
                Fail("localKeyID not found initially");
            }

            store2.SetKeyEntry("new", new AsymmetricKeyEntry(newPair.Private), chain2);

            MemoryStream bOut = new MemoryStream();

            store2.Save(bOut, passwd, new SecureRandom());

            store2.Load(new MemoryStream(bOut.ToArray(), false), passwd);

            chain2 = store2.GetCertificateChain("new");

            if (chain2[1][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
            {
                Fail("localKeyID found after save");
            }
        }
예제 #29
0
        public async Task InstallAsync(string certResponse)
        {
            #region Bouncy castle PKCS #12 cert file generation
            var data = Convert.FromBase64String(certResponse);

            var parser = new X509CertificateParser();
            var cert   = parser.ReadCertificate(data);

            Pkcs12Store          store     = new Pkcs12StoreBuilder().Build();
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);
            store.SetCertificateEntry(cert.SubjectDN.ToString(), certEntry); // use DN as the Alias.

            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(_privateKey);
            store.SetKeyEntry(cert.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { certEntry }); //

            string pfx      = string.Empty;
            string password = "";
            using (MemoryStream ms = new MemoryStream())
            {
                store.Save(ms, password.ToCharArray(), _random);

                ms.Position = 0;
                await _storage.SetAsync("accessCert", ms.GetWindowsRuntimeBuffer());

                StreamReader streamReader = new StreamReader(ms);
                // Write to .PFX string
                byte[] arr = ms.ToArray();

                pfx = CryptographicBuffer.EncodeToBase64String(arr.AsBuffer());
            }
            #endregion
            await _storage.SetAsync(StorageKeyNames.PrivateKey, pfx);

            await CertificateEnrollmentManager.ImportPfxDataAsync(pfx, password, ExportOption.NotExportable, KeyProtectionLevel.NoConsent, InstallOptions.None, "MAG_CERT");

            // Store the registered cert subject
            if (cert.SubjectDN != null)
            {
                var valueList = cert.SubjectDN.GetValueList(X509Name.CN);
                if (valueList.Count > 0)
                {
                    await _storage.SetAsync(StorageKeyNames.RegisteredCertSubject, (string)valueList[0]);
                }
            }
        }
예제 #30
0
        internal byte[] CreatePfxContainer(X509Certificate cert, AsymmetricCipherKeyPair keys)
        {
            var certEntry = new X509CertificateEntry(cert);

            var pkcs12Store = new Pkcs12StoreBuilder()
                              .SetUseDerEncoding(true)
                              .Build();
            var keyEntry = new AsymmetricKeyEntry(keys.Private);

            pkcs12Store.SetKeyEntry("ServerInstance", keyEntry, new X509CertificateEntry[] { certEntry });

            using (MemoryStream stream = new MemoryStream())
            {
                pkcs12Store.Save(stream, null, new SecureRandom());
                var bytes = stream.ToArray();
                return(Pkcs12Utilities.ConvertToDefiniteLength(bytes));
            }
        }
예제 #31
0
		public static void Main(
			string[] args)
		{
//			Security.addProvider(new BouncyCastleProvider());

			//
			// personal keys
			//
//			RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
			RsaKeyParameters pubKey = new RsaKeyParameters(false,
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16));

//			RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
			RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16),
				new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
				new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
				new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
				new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
				new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
				new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));

			//
			// intermediate keys.
			//
//			RSAPublicKeySpec intPubKeySpec = new RSAPublicKeySpec(
			RsaKeyParameters intPubKey = new RsaKeyParameters(false,
				new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16),
				new BigInteger("ffff", 16));


//			RSAPrivateCrtKeySpec intPrivKeySpec = new RSAPrivateCrtKeySpec(
			RsaPrivateCrtKeyParameters intPrivKey = new RsaPrivateCrtKeyParameters(
				new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16),
				new BigInteger("ffff", 16),
				new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16),
				new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16),
				new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16),
				new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16),
				new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16),
				new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16));

			//
			// ca keys
			//
//			RSAPublicKeySpec caPubKeySpec = new RSAPublicKeySpec(
			RsaKeyParameters caPubKey = new RsaKeyParameters(false,
				new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16),
				new BigInteger("11", 16));

//			RSAPrivateCrtKeySpec   caPrivKeySpec = new RSAPrivateCrtKeySpec(
			RsaPrivateCrtKeyParameters caPrivKey = new RsaPrivateCrtKeyParameters(
				new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16),
				new BigInteger("11", 16),
				new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16),
				new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16),
				new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16),
				new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16),
				new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16),
				new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16));



			//
			// set up the keys
			//
//			KeyFactory          fact = KeyFactory.getInstance("RSA", "BC");
//			PrivateKey          caPrivKey = fact.generatePrivate(caPrivKeySpec);
//			PublicKey           caPubKey = fact.generatePublic(caPubKeySpec);
//			PrivateKey          intPrivKey = fact.generatePrivate(intPrivKeySpec);
//			PublicKey           intPubKey = fact.generatePublic(intPubKeySpec);
//			PrivateKey          privKey = fact.generatePrivate(privKeySpec);
//			PublicKey           pubKey = fact.generatePublic(pubKeySpec);

			X509CertificateEntry[] chain = new X509CertificateEntry[3];

			chain[2] = CreateMasterCert(caPubKey, caPrivKey);
			chain[1] = CreateIntermediateCert(intPubKey, caPrivKey, chain[2].Certificate);
			chain[0] = CreateCert(pubKey, intPrivKey, intPubKey);

			//
			// add the friendly name for the private key
			//
//			PKCS12BagAttributeCarrier   bagAttr = (PKCS12BagAttributeCarrier)privKey;
			IDictionary bagAttr = new Hashtable();

			//
			// this is also optional - in the sense that if you leave this
			// out the keystore will add it automatically, note though that
			// for the browser to recognise which certificate the private key
			// is associated with you should at least use the pkcs_9_localKeyId
			// OID and set it to the same as you do for the private key's
			// corresponding certificate.
			//
//			bagAttr.setBagAttribute(
//				PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
//				new DERBMPString("Eric's Key"));
//			bagAttr.setBagAttribute(
//				PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
//				new SubjectKeyIdentifierStructure(pubKey));
			bagAttr.Add(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id,
				new DerBmpString("Eric's Key"));
			bagAttr.Add(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id,
				new SubjectKeyIdentifierStructure(pubKey));

			//
			// store the key and the certificate chain
			//
//			KeyStore store = KeyStore.getInstance("PKCS12", "BC");
//			store.load(null, null);
			Pkcs12Store store = new Pkcs12StoreBuilder().Build();

			//
			// if you haven't set the friendly name and local key id above
			// the name below will be the name of the key
			//
			store.SetKeyEntry("Eric's Key", new AsymmetricKeyEntry(privKey, bagAttr), chain);

//			FileOutputStream fOut = new FileOutputStream("id.p12");
//
//			store.store(fOut, passwd);
			FileStream fOut = File.Create("id.p12");
			store.Save(fOut, passwd, new SecureRandom());
			fOut.Close();
		}