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); }
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; } } }
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(); }
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)); } }
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()))); } }
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); }
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; } }
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()))); } }
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); }
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(); }
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)); }
/// <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())); } }
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)); }
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); }
/// <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; } }
/// <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); }