Exemple #1
0
        public static void ExportToP12(CngKey key, X509Certificate cert, string outputFile, string password, string name)
        {
            // Normalise the name
            string nName = name.Replace(' ', '_');

            // Use the FIPS-140 system prng
            SecureRandom random = new SecureRandom(new CryptoApiRandomGenerator());

            // Build PKCS#12
            Pkcs12StoreBuilder p12  = new Pkcs12StoreBuilder();
            Pkcs12Store        pkcs = p12.Build();

            byte[] privateKey = key.Export(CngKeyBlobFormat.EccPrivateBlob);

            ECPrivateKeyParameters privateParams = EccKeyBlob.UnpackEccPrivateBlob(privateKey);

            pkcs.SetKeyEntry(nName,
                             new AsymmetricKeyEntry(privateParams),
                             new X509CertificateEntry[] { new X509CertificateEntry(cert) });


            Stream stream = new FileStream(outputFile, FileMode.Create);

            pkcs.Save(stream, password.ToCharArray(), random);
            stream.Close();
        }
    /// <summary>
    /// Create a X509Certificate2 with a private key by combining
    /// a bouncy castle X509Certificate and a private key
    /// </summary>
    private static X509Certificate2 CreateCertificateWithPrivateKey(
        Org.BouncyCastle.X509.X509Certificate certificate,
        string friendlyName,
        AsymmetricKeyParameter privateKey,
        SecureRandom random)
    {
        // create pkcs12 store for cert and private key
        using (MemoryStream pfxData = new MemoryStream())
        {
            Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);
            Pkcs12Store            pkcsStore = builder.Build();
            X509CertificateEntry[] chain     = new X509CertificateEntry[1];
            string passcode = Guid.NewGuid().ToString();
            chain[0] = new X509CertificateEntry(certificate);
            if (string.IsNullOrEmpty(friendlyName))
            {
                friendlyName = GetCertificateCommonName(certificate);
            }
            pkcsStore.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(privateKey), chain);
            pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

            // merge into X509Certificate2
            return(CreateCertificateFromPKCS12(pfxData.ToArray(), passcode));
        }
    }
        private static byte[] CreatePfxFile(Org.BouncyCastle.X509.X509Certificate certificate, AsymmetricKeyParameter privateKey, string password = null)
        {
            // create certificate entry
            var    certEntry    = new X509CertificateEntry(certificate);
            string friendlyName = certificate.SubjectDN.ToString();

            // get bytes of private key.
            PrivateKeyInfo keyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);

            byte[] keyBytes = keyInfo.ToAsn1Object().GetEncoded();

            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var store = builder.Build();

            // create store entry
            store.SetKeyEntry("", new AsymmetricKeyEntry(privateKey), new X509CertificateEntry[] { certEntry });
            byte[] pfxBytes = null;
            using (MemoryStream stream = new MemoryStream())
            {
                store.Save(stream, password?.ToCharArray(), new SecureRandom());
                pfxBytes = stream.ToArray();
            }
            var result = Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes);

            return(result);
        }
        private static string SignEnvelop(string signCert, string password, string envelopCert, string orgData)
        {
            var pkcs12StoreBuilder = new Pkcs12StoreBuilder();
            var pkcs12Store        = pkcs12StoreBuilder.Build();

            pkcs12Store.Load(new MemoryStream(Convert.FromBase64String(signCert)), password.ToCharArray());

            var aliases    = pkcs12Store.Aliases;
            var enumerator = aliases.GetEnumerator();

            enumerator.MoveNext();
            var alias   = enumerator.Current.ToString();
            var privKey = pkcs12Store.GetKey(alias);

            var x509Cert   = pkcs12Store.GetCertificate(alias).Certificate;
            var sha1Signer = SignerUtilities.GetSigner("SHA1withRSA");

            sha1Signer.Init(true, privKey.Key);

            var gen = new CmsSignedDataGenerator();

            gen.AddSignerInfoGenerator(new SignerInfoGeneratorBuilder().Build(new Asn1SignatureFactory("SHA1withRSA", privKey.Key), x509Cert));
            gen.AddCertificates(X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(new ArrayList {
                x509Cert
            })));

            var sigData  = gen.Generate(new CmsProcessableByteArray(Encoding.UTF8.GetBytes(orgData)), true);
            var signData = sigData.GetEncoded();

            var certificate = DotNetUtilities.FromX509Certificate(new X509Certificate2(Convert.FromBase64String(envelopCert)));
            var rst         = Convert.ToBase64String(EncryptEnvelop(certificate, signData));

            return(rst);
        }
Exemple #5
0
        private void init(string aPfxFilePath, string aPassword)
        {
            FileStream         fin          = new FileStream(aPfxFilePath, FileMode.Open, FileAccess.Read);
            Pkcs12StoreBuilder storeBuilder = new Pkcs12StoreBuilder();
            Pkcs12Store        pkcs12Store  = storeBuilder.Build();

            pkcs12Store.Load(fin, aPassword.ToCharArray());
            fin.Close();
            IEnumerable aliases           = pkcs12Store.Aliases;
            IEnumerator aliasesEnumerator = aliases.GetEnumerator();

            while (aliasesEnumerator.MoveNext())
            {
                string alias = (string)aliasesEnumerator.Current;
                signingBouncyCert = pkcs12Store.GetCertificate(alias);
                X509Certificate x509Certificate    = signingBouncyCert.Certificate;
                ECertificate    cert               = new ECertificate(x509Certificate.GetEncoded());
                EKeyUsage       eKeyUsage          = cert.getExtensions().getKeyUsage();
                bool            isDigitalSignature = eKeyUsage.isDigitalSignature();
                if (isDigitalSignature)
                {
                    signingBouncyKeyEntry = pkcs12Store.GetKey(alias);
                    signingCertificate    = cert;
                    break;
                }
            }
        }
Exemple #6
0
        internal static void ExportToP12(CspParameters cspParam, X509Certificate cert, string outputFile, string password, string name)
        {
            // Normalise the name
            string nName = name.Replace(' ', '_');

            // Use the FIPS-140 system prng
            SecureRandom random = new SecureRandom(new CryptoApiRandomGenerator());

            // Build PKCS#12
            Pkcs12StoreBuilder p12  = new Pkcs12StoreBuilder();
            Pkcs12Store        pkcs = p12.Build();

            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspParam))
            {
                if (!rsa.CspKeyContainerInfo.Exportable)
                {
                    throw new CryptoException("Private key not exportable");
                }

                pkcs.SetKeyEntry(nName,
                                 new AsymmetricKeyEntry(DotNetUtilities.GetRsaKeyPair(rsa).Private),
                                 new X509CertificateEntry[] { new X509CertificateEntry(cert) });
            }

            Stream stream = new FileStream(outputFile, FileMode.Create);

            pkcs.Save(stream, password.ToCharArray(), random);
            stream.Close();
        }
Exemple #7
0
        private static X509Certificate2 withPrivateKey(X509Certificate certificate, AsymmetricKeyParameter privateKey)
        {
            const string password = "******";
            Pkcs12Store  store;

            if (RunTime.IsRunningOnMono)
            {
                var builder = new Pkcs12StoreBuilder();
                builder.SetUseDerEncoding(true);
                store = builder.Build();
            }
            else
            {
                store = new Pkcs12Store();
            }

            var entry = new X509CertificateEntry(certificate);

            store.SetCertificateEntry(certificate.SubjectDN.ToString(), entry);

            store.SetKeyEntry(certificate.SubjectDN.ToString(), new AsymmetricKeyEntry(privateKey), new[] { entry });
            using (var ms = new MemoryStream())
            {
                store.Save(ms, password.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));

                return(new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable));
            }
        }
Exemple #8
0
        public static X509Certificate2 Load(Stream stream, string password)
        {
            var loadStore = new Pkcs12Store();

            loadStore.Load(stream, password?.ToCharArray());

            string keyAlias = loadStore.Aliases.Cast <string> ().FirstOrDefault(loadStore.IsKeyEntry);

            if (keyAlias == null)
            {
                throw new NotImplementedException("Alias");
            }

            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var saveStore = builder.Build();

            var chain = new X509CertificateEntry(loadStore.GetCertificate(keyAlias).Certificate);

            saveStore.SetCertificateEntry("Alias", chain);
            saveStore.SetKeyEntry("Alias", new AsymmetricKeyEntry((RsaPrivateCrtKeyParameters)loadStore.GetKey(keyAlias).Key), new [] { chain });

            using (var saveStream = new MemoryStream())
            {
                saveStore.Save(saveStream, new char[0], new SecureRandom());
                return(new X509Certificate2(Pkcs12Utilities.ConvertToDefiniteLength(saveStream.ToArray())));
            }
        }
Exemple #9
0
        internal static CertContainer IssueSignerCertificate(X509Name dnName, int keySize = DefaultKeySize)
        {
            CertContainer issuerCert = IntermediateCa;

            RsaKeyPairGenerator keyPairGen = new RsaKeyPairGenerator();

            keyPairGen.Init(new KeyGenerationParameters(_secureRandom, keySize));
            AsymmetricCipherKeyPair keyPair = keyPairGen.GenerateKeyPair();

            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

            certGen.SetSerialNumber(BigInteger.One);
            certGen.SetIssuerDN(issuerCert.Certificate.SubjectDN);
            certGen.SetNotBefore(DateTime.Now);
            certGen.SetNotAfter(DateTime.Now.AddYears(1));

            certGen.SetSubjectDN(dnName);
            certGen.SetPublicKey(keyPair.Public);
            certGen.SetSignatureAlgorithm("SHA256withRSA");
            certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(issuerCert.Certificate.GetPublicKey()));
            certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));
            certGen.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(X509KeyUsage.NonRepudiation | X509KeyUsage.DigitalSignature));
            certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keyPair.Public));
            certGen.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeID.IdKPClientAuth));

            // Add CRL endpoint
            Uri currentBaseUri = new Uri("https://localhost/");
            Uri crlUri         = new Uri(currentBaseUri, IntermediateCrlPath);

            GeneralName           generalName   = new GeneralName(GeneralName.UniformResourceIdentifier, crlUri.ToString());
            GeneralNames          generalNames  = new GeneralNames(generalName);
            DistributionPointName distPointName = new DistributionPointName(generalNames);
            DistributionPoint     distPoint     = new DistributionPoint(distPointName, null, null);

            certGen.AddExtension(X509Extensions.CrlDistributionPoints, false, new CrlDistPoint(new DistributionPoint[] { distPoint }));

            // Add OCSP endpoint
            Uri ocspUri            = new Uri(currentBaseUri, OcspPath);
            AccessDescription ocsp = new AccessDescription(AccessDescription.IdADOcsp,
                                                           new GeneralName(GeneralName.UniformResourceIdentifier, ocspUri.ToString()));

            Asn1EncodableVector aiaASN = new Asn1EncodableVector();

            aiaASN.Add(ocsp);

            certGen.AddExtension(X509Extensions.AuthorityInfoAccess, false, new DerSequence(aiaASN));

            X509Certificate generatedCert = certGen.Generate(issuerCert.PrivateKey);

            Pkcs12StoreBuilder pfxBuilder = new Pkcs12StoreBuilder();
            Pkcs12Store        pfxStore   = pfxBuilder.Build();

            X509CertificateEntry certEntry = new X509CertificateEntry(generatedCert);

            pfxStore.SetCertificateEntry(generatedCert.SubjectDN.ToString(), certEntry);
            pfxStore.SetKeyEntry(generatedCert.SubjectDN + "_key", new AsymmetricKeyEntry(keyPair.Private), new X509CertificateEntry[] { certEntry });

            return(new CertContainer(pfxStore, issuerCert.GetIssuerChain(true)));
        }
        public KeyStoreViewModel(SystemX509.StoreName storeName, SystemX509.StoreLocation storeLocation)
        {
            var storeBuilder = new Pkcs12StoreBuilder();

            _store = storeBuilder.Build();
            Name   = String.Format("System KeyStore: [{0} : {1}]", storeLocation.ToString(), storeName.ToString());
            Load(storeName, storeLocation);
        }
Exemple #11
0
        private void keyStoreTest(
            IAsymmetricKeyParameter sKey,
            IAsymmetricKeyParameter vKey)
//	        throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
        {
            //
            // keystore test
            //
//			KeyStore ks = KeyStore.GetInstance("JKS");
//			ks.Load(null, null);
            Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder();
            Pkcs12Store        ks        = ksBuilder.Build();

            //
            // create the certificate - version 3
            //
            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

            certGen.SetSerialNumber(BigInteger.One);
            certGen.SetIssuerDN(new X509Name("CN=Test"));
            certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
            certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
            certGen.SetSubjectDN(new X509Name("CN=Test"));
            certGen.SetPublicKey(vKey);
            certGen.SetSignatureAlgorithm("GOST3411withGOST3410");

            X509Certificate      cert      = certGen.Generate(sKey);
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);

//	        ks.SetKeyEntry("gost", sKey, "gost".ToCharArray(), new X509Certificate[] { cert });
            ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry });

            MemoryStream bOut = new MemoryStream();

            ks.Save(bOut, "gost".ToCharArray(), new SecureRandom());

//	        ks = KeyStore.getInstance("JKS");
            ks = ksBuilder.Build();

            ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray());

//	        IAsymmetricKeyParameter gKey = (AsymmetricKeyParameter)ks.GetKey("gost", "gost".ToCharArray());
//	        AsymmetricKeyEntry gKeyEntry = (AsymmetricKeyEntry)
            ks.GetKey("gost");
        }
        /// <summary>
        /// Genera el archivo pfx y devuelve el resultado con su contraseña
        /// </summary>
        /// <param name="rutaArchivoCer"></param>
        /// <param name="rutaArchivoKey"></param>
        /// <param name="secretArchivoKey"></param>
        /// <param name="rutaGuardado"></param>
        /// <param name="nombreArchivoPfx"></param>
        /// <param name="secretArchivoPfx"></param>
        /// <param name="conservarArchivo"></param>
        /// <returns>Pfx</returns>
        public static CfdiPfx generarArchivoPfx(string rutaArchivoCer, string rutaArchivoKey, string secretArchivoKey, string rutaGuardado, string nombreArchivoPfx, string secretArchivoPfx, Boolean conservarArchivo)
        {
            try
            {
                string rutaArchivoPfx = Path.Combine(rutaGuardado, nombreArchivoPfx);

                if (!Directory.Exists(rutaGuardado))
                {
                    Directory.CreateDirectory(rutaGuardado);
                }

                if (File.Exists(rutaArchivoPfx))
                {
                    File.Delete(rutaArchivoPfx);
                }

                X509Certificate2 certificado = new X509Certificate2(rutaArchivoCer);
                Org.BouncyCastle.X509.X509Certificate certificate = DotNetUtilities.FromX509Certificate(certificado);

                byte[] bytesArchivoKey            = File.ReadAllBytes(rutaArchivoKey);
                AsymmetricKeyParameter privateKey = PrivateKeyFactory.DecryptKey(secretArchivoKey.ToCharArray(), bytesArchivoKey);

                var    certEntry    = new X509CertificateEntry(certificate);
                string friendlyName = certificate.SubjectDN.ToString();

                PrivateKeyInfo keyInfo  = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
                byte[]         keyBytes = keyInfo.ToAsn1Object().GetEncoded();

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

                store.SetKeyEntry("PrivateKeyAlias", new AsymmetricKeyEntry(privateKey), new X509CertificateEntry[] { certEntry });

                byte[] pfxBytes = null;

                using (MemoryStream stream = new MemoryStream())
                {
                    store.Save(stream, secretArchivoPfx.ToCharArray(), new SecureRandom());
                    pfxBytes = stream.ToArray(); // Este sirve para la cancelacion
                }

                var result = Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes);

                if (conservarArchivo)
                {
                    File.WriteAllBytes(rutaArchivoPfx, result);
                }

                return(new CfdiPfx(result, secretArchivoPfx));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemple #13
0
        public static X509Certificate2 LoadFromUnencryptedPEM(string pem)
        {
            //Extract certificate
            var pattern     = new Regex(@"^[-]{5}BEGIN CERTIFICATE[-]{5}(?<certificate>([^-]*))[-]{5}END CERTIFICATE[-]{5}", RegexOptions.Multiline);
            var pvk_pattern = new Regex(@"[-]{5}BEGIN(?<encrypted>( ENCRYPTED)?) PRIVATE KEY[-]{5}(?<key>([^-]*))[-]{5}END( ENCRYPTED)? PRIVATE KEY[-]{5}", RegexOptions.Multiline);

            if (!pattern.IsMatch(pem))
            {
                throw new ArgumentException("Certificate malformed. (No certitficates found)");
            }
            if (!pvk_pattern.IsMatch(pem))
            {
                throw new ArgumentException("Certificate malformed. (No private key found)");
            }

            //Read all certificates to a jagged byte array
            MatchCollection mc           = pattern.Matches(pem);
            var             certificates = new byte[mc.Count][];
            var             index        = 0;

            foreach (Match match in mc)
            {
                certificates[index] = Convert.FromBase64String(match.Groups["certificate"].ToString().Trim(Environment.NewLine.ToCharArray()));
                index++;
            }
            //If the private key is encrypted (check on "encrypted" group) then that need to be handled in future, probably never.
            Match  pvk_match = pvk_pattern.Match(pem);
            string pvk       = pvk_match.Groups["key"].ToString();

            var parser            = new X509CertificateParser();
            var parsedCertificate = parser.ReadCertificate(Combine(certificates));

            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var inputKeyStore = builder.Build();

            inputKeyStore.SetCertificateEntry("Alias", new X509CertificateEntry(parsedCertificate));
            inputKeyStore.SetKeyEntry("Alias", new AsymmetricKeyEntry((RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(pvk))), new [] { new X509CertificateEntry(parsedCertificate) });

            string keyAlias = inputKeyStore.Aliases.Cast <string> ().FirstOrDefault(inputKeyStore.IsKeyEntry);

            if (keyAlias == null)
            {
                throw new InvalidKeyException("Alias");
            }

            using (var stream = new MemoryStream())
            {
                //There is no password
                inputKeyStore.Save(stream, new char[0], new SecureRandom());
                return(new X509Certificate2(Pkcs12Utilities.ConvertToDefiniteLength(stream.ToArray())));
            }
        }
Exemple #14
0
        internal static string SaveP12(AsymmetricKeyParameter privateKey, X509Certificate cert, string keyFile, string password, string alias)
        {
            // Use the FIPS-140 system prng
            SecureRandom random = new SecureRandom(new CryptoApiRandomGenerator());

            // Build PKCS#12
            Pkcs12StoreBuilder p12  = new Pkcs12StoreBuilder();
            Pkcs12Store        pkcs = p12.Build();

            pkcs.SetKeyEntry(alias, new AsymmetricKeyEntry(privateKey), new X509CertificateEntry[] { new X509CertificateEntry(cert) });

            Stream stream = new FileStream(keyFile, FileMode.Create);

            pkcs.Save(stream, password.ToCharArray(), random);
            stream.Close();
            return(alias);
        }
Exemple #15
0
        private static byte[] CreatePfxFile(X509Certificate certificate, AsymmetricKeyParameter privateKey, string name, string password)
        {
            var certEntry = new X509CertificateEntry(certificate);

            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var store = builder.Build();

            store.SetKeyEntry(name, new AsymmetricKeyEntry(privateKey), new X509CertificateEntry[] { certEntry });

            using MemoryStream stream = new MemoryStream();
            store.Save(stream, password.ToCharArray(), new SecureRandom());
            var pfxBytes = stream.ToArray();
            var result   = Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes);

            return(result);
        }
        /// <summary>
        /// Loads the keystore from the <code>Repository.Instance.CertificatesKeyStore</code>
        /// You shud call <code>Repository.Instance.OpenExistingCertificateAuthority</code>
        /// before calling this.
        /// </summary>
        /// <param name="password">password for the keystore</param>
        public KeyStoreViewModel(char[] password, String path)
        {
            if (!Repository.Instance.OpenExistingCertificateAuthority(path, password))
            {
                throw new Exception("Unable to open KeyStore. Invalid keystore directory");
            }
            Name             = Path.GetFileName(path);
            ReadOnlyKeyStore = false;
            _password        = password;
            _listItems.Clear();
            var storeBuilder = new Pkcs12StoreBuilder();

            _store             = storeBuilder.Build();
            _x509CertViewModel = new X509CertViewModel((alias, cert, keypair) =>
            {
                AddEntry(alias, cert, keypair);
                ShowCertificateGenerator = false;
            });
            Load();
        }
Exemple #17
0
        public static byte[] CreatePKCS12(X509Certificate certificate, AsymmetricKeyParameter privateKey, string password)
        {
            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var store = builder.Build();

            var certEntry = new X509CertificateEntry(certificate);

            store.SetKeyEntry("some_alias",
                              new AsymmetricKeyEntry(privateKey),
                              new X509CertificateEntry[] { certEntry });

            byte[] pfxBytes;
            using (MemoryStream stream = new MemoryStream()) {
                store.Save(stream, password.ToCharArray(), new SecureRandom());
                pfxBytes = stream.ToArray();
            }

            return(Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes));
        }
Exemple #18
0
        /// <summary>
        /// 我也不晓得这个叫什么
        /// </summary>
        /// <param name="orgData"></param>
        /// <returns></returns>
        public static string SignEnvelop(string orgData)
        {
            Pkcs12StoreBuilder pkcs12StoreBuilder = new Pkcs12StoreBuilder();
            var pkcs12Store = pkcs12StoreBuilder.Build();

            pkcs12Store.Load(File.OpenRead(PfxPath), pfxPwd.ToCharArray());
            IEnumerable aliases    = pkcs12Store.Aliases;
            var         enumerator = aliases.GetEnumerator();

            enumerator.MoveNext();
            var alias   = enumerator.Current.ToString();
            var privKey = pkcs12Store.GetKey(alias);

            var x509Cert   = pkcs12Store.GetCertificate(alias).Certificate;
            var sha1Signer = SignerUtilities.GetSigner("SHA1withRSA");

            sha1Signer.Init(true, privKey.Key);

            var bs = Encoding.UTF8.GetBytes(orgData);

            CmsSignedDataGenerator gen = new CmsSignedDataGenerator();

            gen.AddSignerInfoGenerator(
                new SignerInfoGeneratorBuilder().Build(new Asn1SignatureFactory("SHA1withRSA", privKey.Key), x509Cert));
            IList certList = new ArrayList();

            certList.Add(x509Cert);
            gen.AddCertificates(X509StoreFactory.Create("Certificate/Collection",
                                                        new X509CollectionStoreParameters(certList)));
            var msg      = new CmsProcessableByteArray(bs);
            var sigData  = gen.Generate(msg, true);
            var signData = sigData.GetEncoded();

            var certificate = DotNetUtilities.FromX509Certificate(new SystemX509.X509Certificate(CertPath));
            var rst         = Convert.ToBase64String(EncryptEnvelop(certificate, signData));

            return(rst);
        }
        /// <summary>
        /// Create pfx
        /// </summary>
        /// <param name="certificate"></param>
        /// <param name="privateKey"></param>
        /// <param name="password"></param>
        internal static byte[] ToPfx(this X509Certificate certificate,
                                     AsymmetricKeyParameter privateKey, string password = null)
        {
            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var store = builder.Build();

            // create store entry
            var friendlyName = certificate.SubjectDN.ToString();

            store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(privateKey),
                              new X509CertificateEntry[] {
                new X509CertificateEntry(certificate)
            });
            using (var stream = new MemoryStream()) {
                using (var cfrg = new RandomGeneratorAdapter()) {
                    store.Save(stream, (password ?? string.Empty).ToCharArray(),
                               new SecureRandom(cfrg));
                }
                return(Pkcs12Utilities.ConvertToDefiniteLength(stream.ToArray()));
            }
        }
Exemple #20
0
        private byte[] CreatePfxFile(Org.BouncyCastle.X509.X509Certificate cert, AsymmetricKeyParameter privateKey, string password, string keyFriendlyName)
        {
            var certEntry    = new X509CertificateEntry(cert);
            var friendlyName = cert.SubjectDN.ToString();

            var keyInfo  = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
            var keyBytes = keyInfo.ToAsn1Object().GetEncoded();

            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            var store = builder.Build();

            store.SetKeyEntry(keyFriendlyName, new AsymmetricKeyEntry(privateKey), new[] { certEntry });
            byte[] pfxBytes;

            using (var ms = new MemoryStream())
            {
                store.Save(ms, password.ToCharArray(), new SecureRandom());
                pfxBytes = ms.ToArray();
            }

            return(Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes));
        }
        ///// <summary>
        ///// Create a new certificate
        ///// </summary>
        ///// <param name="issuer">Issuer certificate, if null then self-sign</param>
        ///// <param name="subjectName">Subject name</param>
        ///// <param name="serialNumber">Serial number of certificate, if null then will generate a new one</param>
        ///// <param name="keySize">Size of RSA key</param>
        ///// <param name="notBefore">Start date of certificate</param>
        ///// <param name="notAfter">End date of certificate</param>
        ///// <param name="extensions">Array of extensions, if null then no extensions</param>
        ///// <param name="hashAlgorithm">Specify the signature hash algorithm</param>
        ///// <returns>The created X509 certificate</returns>
        public static SystemX509.X509Certificate2 CreateCert(SystemX509.X509Certificate2 issuer, SystemX509.X500DistinguishedName subjectName,
                                                             byte[] serialNumber, int keySize, CertificateHashAlgorithm hashAlgorithm, DateTime notBefore,
                                                             DateTime notAfter, SystemX509.X509ExtensionCollection extensions)
        {
            SecureRandom random = new SecureRandom();
            X509V3CertificateGenerator builder      = new X509V3CertificateGenerator();
            AsymmetricCipherKeyPair    bcSubjectKey = CreateRSAKey(keySize, random);
            AsymmetricCipherKeyPair    bcSignKey    = issuer == null ? bcSubjectKey : issuer.GetBCPrivateKey();

            if (bcSignKey == null)
            {
                throw new ArgumentException("issuer");
            }

            X509Name issuerNameObj = issuer == null?X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData))
                                         : X509Name.GetInstance(Asn1Object.FromByteArray(issuer.SubjectName.RawData));

            X509Name subjectNameObj = X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData));

            BigInteger subjectSerial = new BigInteger(1, serialNumber != null ? serialNumber : Guid.NewGuid().ToByteArray());
            BigInteger issuerSerial  = issuer == null ? subjectSerial : new BigInteger(1, issuer.GetSerialNumber());

            builder.SetIssuerDN(issuerNameObj);
            builder.SetSubjectDN(subjectNameObj);
            builder.SetSerialNumber(subjectSerial);
            builder.SetNotBefore(notBefore.ToUniversalTime());
            builder.SetNotAfter(notAfter.ToUniversalTime());
            builder.SetPublicKey(bcSubjectKey.Public);

            SubjectPublicKeyInfo   info         = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSignKey.Public);
            AuthorityKeyIdentifier authKeyId    = new AuthorityKeyIdentifier(info, new GeneralNames(new GeneralName(issuerNameObj)), issuerSerial);
            SubjectKeyIdentifier   subjectKeyid = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSubjectKey.Public));

            builder.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, true, authKeyId);
            builder.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, true, subjectKeyid);

            if (extensions != null)
            {
                foreach (SystemX509.X509Extension ext in extensions)
                {
                    if (!ext.Oid.Value.Equals(X509Extensions.AuthorityKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(X509Extensions.SubjectKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(szOID_AUTHORITY_KEY_IDENTIFIER2))
                    {
                        Asn1InputStream istm = new Asn1InputStream(ext.RawData);
                        Asn1Object      obj  = istm.ReadObject();
                        builder.AddExtension(ext.Oid.Value, ext.Critical, obj);
                    }
                }
            }

            X509Certificate cert = builder.Generate(CreateSignatureFactory(hashAlgorithm, bcSignKey, random));

            Pkcs12StoreBuilder   pkcs  = new Pkcs12StoreBuilder();
            Pkcs12Store          store = pkcs.Build();
            X509CertificateEntry entry = new X509CertificateEntry(cert);

            store.SetCertificateEntry("main", entry);

            AsymmetricKeyEntry key_entry = new AsymmetricKeyEntry(bcSubjectKey.Private);

            store.SetKeyEntry("main", key_entry, new[] { entry });
            MemoryStream stm = new MemoryStream();

            store.Save(stm, new char[0], new SecureRandom());
            return(new SystemX509.X509Certificate2(stm.ToArray(), String.Empty, SystemX509.X509KeyStorageFlags.Exportable));
        }
Exemple #22
0
        public static bool ExportAsPkcs12(this IKeySet keySet, Stream saveStream, Func <string> passwordPrompt)
        {
            var issuerGenerator = new RsaKeyPairGenerator();

            issuerGenerator.Init(new KeyGenerationParameters(Secure.Random, 2048));

            var issuerKp = issuerGenerator.GenerateKeyPair();


            var        issuercn          = new X509Name($"CN=Keyczar|{keySet.Metadata.Name}|TEMPCA");
            var        issuerGenertor    = new X509V3CertificateGenerator();
            BigInteger issueSerialNumber = BigInteger.ProbablePrime(128, Secure.Random);

            issuerGenertor.SetSerialNumber(issueSerialNumber);
            issuerGenertor.SetSubjectDN(issuercn);
            issuerGenertor.SetIssuerDN(issuercn);
            issuerGenertor.SetNotAfter(DateTime.Now.AddYears(100));
            issuerGenertor.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
            issuerGenertor.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeID.AnyExtendedKeyUsage));
            issuerGenertor.SetPublicKey(issuerKp.Public);
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKp.Private, Secure.Random);
            var issuerCert = issuerGenertor.Generate(signatureFactory);

            var builder = new Pkcs12StoreBuilder();

            var store = builder.Build();

            var issueEntryCert = new X509CertificateEntry(issuerCert);
            var hasPrivateKeys = false;

            foreach (var version in keySet.Metadata.Versions)
            {
                using (var key = keySet.GetKey(version.VersionNumber))
                {
                    var        cn = new X509Name($"CN=Keyczar|{keySet.Metadata.Name}|{version.VersionNumber}");
                    var        certificateGenerator = new X509V3CertificateGenerator();
                    BigInteger serialNo             = BigInteger.ProbablePrime(128, Secure.Random);
                    certificateGenerator.SetSerialNumber(serialNo);
                    certificateGenerator.SetSubjectDN(cn);
                    certificateGenerator.SetIssuerDN(issuercn);
                    certificateGenerator.SetNotAfter(DateTime.Now.AddYears(100));
                    certificateGenerator.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
                    certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeID.AnyExtendedKeyUsage));
                    switch (key)
                    {
                    case IRsaPrivateKey k:
                    {
                        hasPrivateKeys = true;
                        var publicKey  = BouncyCastleFromKey(k.PublicKey);
                        var privateKey = BouncyCastleFromKey(k);

                        certificateGenerator.SetPublicKey(publicKey);
                        var certificate = certificateGenerator.Generate(signatureFactory);

                        var entryCert = new X509CertificateEntry(certificate);
                        store.SetCertificateEntry(certificate.SubjectDN.ToString(), entryCert);

                        var keyEntry = new AsymmetricKeyEntry(privateKey);
                        store.SetKeyEntry(certificate.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { entryCert, issueEntryCert });
                    }
                    break;

                    case IRsaPublicKey rsaPub:
                    {
                        var publicKey = BouncyCastleFromKey(rsaPub);
                        certificateGenerator.SetPublicKey(publicKey);
                        var certificate = certificateGenerator.Generate(signatureFactory);
                        var entryCert   = new X509CertificateEntry(certificate);
                        store.SetCertificateEntry(certificate.SubjectDN.ToString(), entryCert);
                    }
                    break;

                    case DsaPrivateKey dsaKey:
                    {
                        hasPrivateKeys = true;
                        var publicKey  = BouncyCastleFromKey(dsaKey.PublicKey);
                        var privateKey = BouncyCastleFromKey(dsaKey);
                        certificateGenerator.SetPublicKey(publicKey);
                        var certificate = certificateGenerator.Generate(signatureFactory);

                        var entryCert = new X509CertificateEntry(certificate);
                        store.SetCertificateEntry(certificate.SubjectDN.ToString(), entryCert);

                        var keyEntry = new AsymmetricKeyEntry(privateKey);
                        store.SetKeyEntry(certificate.SubjectDN.ToString() + "|key", keyEntry, new X509CertificateEntry[] { entryCert, issueEntryCert });
                    }
                    break;

                    case DsaPublicKey dsaKey:
                    {
                        var publicKey = BouncyCastleFromKey(dsaKey);
                        certificateGenerator.SetPublicKey(publicKey);
                        var certificate = certificateGenerator.Generate(signatureFactory);
                        var entryCert   = new X509CertificateEntry(certificate);
                        store.SetCertificateEntry(certificate.SubjectDN.ToString(), entryCert);
                    }
                    break;
                    }
                }
            }


            if (!hasPrivateKeys)
            {
                passwordPrompt = null;
            }
            var password = passwordPrompt?.Invoke();

            if (String.IsNullOrEmpty(password))
            {
                password = null;
            }

            store.Save(saveStream, password?.ToCharArray(), new SecureRandom());

            return(true);
        }
Exemple #23
0
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>
        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword,
                                              bool addtoStore = false)
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();

            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;

            // create the CN using the name passed in and create a unique serial number for the cert
            var        certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();

            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);

            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth });

            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??
            x509Generator.SetSignatureAlgorithm("sha1WithRSA");
            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(cerKp.Private);

            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12,
                                                                                      userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry    = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(2000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();

            store.SetCertificateEntry("Elastacloud Test Certificate", entry);
            store.SetKeyEntry("Elastacloud Test Certificate", keyEntry, new[] { entry });
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

            // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);

            // if specified then this add this certificate to the store
            if (addtoStore)
            {
                AddToMyStore(cert);
            }

            return(cert);
        }
        /// <summary>
        /// Creates a cert with the connectionstring (token) and stores it in the given cert store.
        /// </summary>
        public async static Task WriteAsync(string name, string connectionString, string storeType, string storePath)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                throw new ArgumentException("Token not found in X509Store and no new token provided!");
            }

            SecureRandom            random = new SecureRandom();
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048);
            RsaKeyPairGenerator     keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);
            AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair();

            ArrayList nameOids = new ArrayList();

            nameOids.Add(X509Name.CN);
            ArrayList nameValues = new ArrayList();

            nameValues.Add(name);
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN  = subjectDN;

            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random));
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);
            cg.SetNotBefore(DateTime.Now);
            cg.SetNotAfter(DateTime.Now.AddMonths(12));
            cg.SetPublicKey(keys.Public);
            cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment));

            // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and
            // "hide" it in the instruction code cert extension
            RSA              rsa       = RSA.Create();
            RSAParameters    rsaParams = new RSAParameters();
            RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public;

            rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length];
            keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0);

            rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length];
            keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0);

            rsa.ImportParameters(rsaParams);
            if (rsa != null)
            {
                byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1);
                if (bytes != null)
                {
                    cg.AddExtension(X509Extensions.InstructionCode, false, bytes);
                }
                else
                {
                    RsaUtils.RSADispose(rsa);
                    throw new CryptographicException("Can not encrypt IoTHub security token using generated public key!");
                }
            }
            RsaUtils.RSADispose(rsa);

            // sign the cert with the private key
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random);

            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create a PKCS12 store for the cert and its private key
            X509Certificate2 certificate = null;

            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder();
                builder.SetUseDerEncoding(true);
                Pkcs12Store            pkcsStore = builder.Build();
                X509CertificateEntry[] chain     = new X509CertificateEntry[1];
                string passcode = Guid.NewGuid().ToString();
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // create X509Certificate2 object from PKCS12 file
                certificate = CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);

                // handle each store type differently
                switch (storeType)
                {
                case CertificateStoreType.Directory:
                {
                    // Add to DirectoryStore
                    using (DirectoryCertificateStore store = new DirectoryCertificateStore())
                    {
                        store.Open(storePath);
                        X509CertificateCollection certificates = await store.Enumerate();

                        // remove any existing cert with our name from the store
                        foreach (X509Certificate2 cert in certificates)
                        {
                            if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase))
                            {
                                await store.Delete(cert.Thumbprint);
                            }
                        }

                        // add new one
                        await store.Add(certificate);
                    }
                    break;
                }

                case CertificateStoreType.X509Store:
                {
                    // Add to X509Store
                    using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser))
                    {
                        store.Open(OpenFlags.ReadWrite);

                        // remove any existing cert with our name from the store
                        foreach (X509Certificate2 cert in store.Certificates)
                        {
                            if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase))
                            {
                                store.Remove(cert);
                            }
                        }

                        // add new cert to store
                        try
                        {
                            store.Add(certificate);
                        }
                        catch (Exception e)
                        {
                            throw new Exception($"Not able to add cert to the requested store type '{storeType}' (exception message: '{e.Message}'.");
                        }
                    }
                    break;
                }

                default:
                {
                    throw new Exception($"The requested store type '{storeType}' is not supported. Please change.");
                }
                }
                return;
            }
        }
Exemple #25
0
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>

        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword, bool addtoStore = false, string exportDirectory = @"Models\Encryption\Certificates\")
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();

            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;


            // create the CN using the name passed in and create a unique serial number for the cert
            var        certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();

            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);

            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth });

            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??


            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", cerKp.Private);

            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(signatureFactory);


            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12, userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry    = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();

            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha256WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha256WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(10000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();

            store.SetCertificateEntry("Created by Blockchain", entry);
            store.SetKeyEntry("Created by Blockchain", keyEntry, new[] { entry });
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

            // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);

            // set up the PEM writer too
            if (exportDirectory != null)
            {
                var textWriter = new StringWriter();
                var pemWriter  = new PemWriter(textWriter);
                pemWriter.WriteObject(cerKp.Private, "DESEDE", userPassword.ToCharArray(), new SecureRandom());

                pemWriter.Writer.Flush();
                string privateKeyPem = textWriter.ToString();
                using (var writer = new StreamWriter(Path.Combine(exportDirectory, cert.Thumbprint + ".pem")))
                {
                    writer.WriteLine(privateKeyPem);
                }
                // also export the certs - first the .pfx
                byte[] privateKeyBytes = cert.Export(X509ContentType.Pfx, userPassword);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".pfx"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(privateKeyBytes, 0, privateKeyBytes.Length);
                }
                // also export the certs - then the .cer
                byte[] publicKeyBytes = cert.Export(X509ContentType.Cert);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".cer"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(publicKeyBytes, 0, publicKeyBytes.Length);
                }
            }

            // if specified then this add this certificate to the store
            if (addtoStore)
            {
                AddToMyStore(cert);
            }

            return(cert);
        }