/// <summary> /// Create a X509Certificate2 with a private key by combining /// a bouncy castle X509Certificate and private key parameters. /// </summary> private static X509Certificate2 CreateCertificateWithPrivateKey( Org.BouncyCastle.X509.X509Certificate certificate, string friendlyName, Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey, Org.BouncyCastle.Security.SecureRandom random) { // create pkcs12 store for cert and private key using (MemoryStream pfxData = new MemoryStream()) { var builder = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); var pkcsStore = builder.Build(); var chain = new Org.BouncyCastle.Pkcs.X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate); if (string.IsNullOrEmpty(friendlyName)) { friendlyName = GetCertificateCommonName(certificate); } pkcsStore.SetKeyEntry(friendlyName, new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(privateKey), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // merge into X509Certificate2 return(CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode)); } }
/// <summary> /// Zertifikat mit privatem Schlüssel verknüpfen. /// </summary> /// <param name="cert">Zertifikat</param> /// <param name="rsa">Privater Schlüssel</param> /// <param name="keyPwd">Passwort mit dem das Zertifikat verschlüsselt werden soll.</param> /// <returns>Neues Zertifikat</returns> private static SystemX509.X509Certificate2 LinkPrivateKeyToCert( SystemX509.X509Certificate2 cert, System.Security.Cryptography.RSACryptoServiceProvider rsa, System.Security.SecureString keyPwd) { var pkcs12store = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder().Build(); var rsaKeyPair = GetRsaKeyPair(rsa); var bcCert = FromX509Certificate(cert); var pkcs12data = LinkPrivateKeyToCert(bcCert, rsaKeyPair, keyPwd); var testCert = new SystemX509.X509Certificate2(pkcs12data, keyPwd, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet); return(testCert); }
/// <summary> /// Zertifikat mit privatem Schlüssel verknüpfen. (BouncyCastle-Teil) /// </summary> /// <param name="bcCert">Zertifikat</param> /// <param name="rsaKeyPair">Private Schlüssel</param> /// <param name="keyPwd">Passwort mit dem das Zertifikat verschlüsselt werden soll.</param> /// <returns></returns> private static byte[] LinkPrivateKeyToCert( Org.BouncyCastle.X509.X509Certificate bcCert, Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair rsaKeyPair, System.Security.SecureString keyPwd) { var pkcs12store = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder().Build(); pkcs12store.SetKeyEntry(string.Empty, new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(rsaKeyPair.Private), new[] { new Org.BouncyCastle.Pkcs.X509CertificateEntry(bcCert) }); var pkcs12data = new System.IO.MemoryStream(); pkcs12store.Save(pkcs12data, keyPwd.ToUnencryptedString().ToCharArray(), new Org.BouncyCastle.Security.SecureRandom(new CryptoApiRandomGenerator())); return(pkcs12data.ToArray()); }
public static byte[] CreatePfxBytes( Org.BouncyCastle.X509.X509Certificate certificate , Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey , string password = "") { byte[] pfxBytes = null; // create certificate entry Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry = new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate); Org.BouncyCastle.Asn1.X509.X509Name name = new Org.BouncyCastle.Asn1.X509.X509Name(certificate.SubjectDN.ToString()); string friendlyName = (string)name.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.O)[0]; if (System.StringComparer.InvariantCultureIgnoreCase.Equals("Skynet Earth Inc.", friendlyName)) { friendlyName = "Skynet Certification Authority"; } Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder builder = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); Org.BouncyCastle.Pkcs.Pkcs12Store store = builder.Build(); store.SetCertificateEntry(friendlyName, certEntry); // create store entry store.SetKeyEntry( friendlyName , new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(privateKey) , new Org.BouncyCastle.Pkcs.X509CertificateEntry[] { certEntry } ); using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { // Cert is contained in store // null: no password, "": an empty passwords // note: Linux needs empty password on null... store.Save(stream, password == null ? "".ToCharArray() : password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom()); // stream.Position = 0; pfxBytes = Org.BouncyCastle.Pkcs.Pkcs12Utilities.ConvertToDefiniteLength(stream.ToArray()); } // End Using stream return(pfxBytes); } // End Function CreatePfxBytes
} // End Function ReadPrivateKey public static void TestSignature() { System.Console.WriteLine("Attempting to load cert..."); System.Security.Cryptography.X509Certificates.X509Certificate2 thisCert = null; // LoadCertificate(); System.Console.WriteLine(thisCert.IssuerName.Name); System.Console.WriteLine("Signing the text - Mary had a nuclear bomb"); byte[] pkcs12Bytes = thisCert.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "dummy"); Org.BouncyCastle.Pkcs.Pkcs12Store pkcs12 = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder().Build(); pkcs12.Load(new System.IO.MemoryStream(pkcs12Bytes, false), "dummy".ToCharArray()); Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters privKey = null; foreach (string alias in pkcs12.Aliases) { if (pkcs12.IsKeyEntry(alias)) { privKey = (Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters)pkcs12.GetKey(alias).Key; break; } // End if (pkcs12.IsKeyEntry(alias)) } // Next alias string signature = SignData("Mary had a nuclear bomb", privKey); System.Console.WriteLine("Signature: " + signature); System.Console.WriteLine("Verifying Signature"); Org.BouncyCastle.X509.X509Certificate bcCert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(thisCert); if (VerifySignature((Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)bcCert.GetPublicKey(), signature, "Mary had a nuclear bomb.")) { System.Console.WriteLine("Valid Signature!"); } else { System.Console.WriteLine("Signature NOT valid!"); } } // End Sub TestSignature
// System.Security.Cryptography.X509Certificates.X509Certificate2.Import (string fileName); // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.import?view=netframework-4.7.2 // https://gist.github.com/yutopio/a217a4af63cf6bcf0a530c14c074cf8f // https://gist.githubusercontent.com/yutopio/a217a4af63cf6bcf0a530c14c074cf8f/raw/42b2f8cb27f6d22b7e22d65da5bbd0f1ce9b2fff/cert.cs // https://stackoverflow.com/questions/44755155/store-pkcs12-container-pfx-with-bouncycastle // https://github.com/Worlaf/RSADemo/blob/328692e28e48db92340d55563480c8724d916384/RSADemo_WinForms/frmRsaDemo.cs public static void Create( string fileName , Org.BouncyCastle.X509.X509Certificate certificate , Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey , string password = "") { // create certificate entry Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry = new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate); Org.BouncyCastle.Asn1.X509.X509Name name = new Org.BouncyCastle.Asn1.X509.X509Name(certificate.SubjectDN.ToString()); string friendlyName = name .GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.O) .OfType <string>() .FirstOrDefault(); if (System.StringComparer.InvariantCultureIgnoreCase.Equals("Skynet Earth Inc.", friendlyName)) { friendlyName = "Skynet Certification Authority"; } // get bytes of private key. Org.BouncyCastle.Asn1.Pkcs.PrivateKeyInfo keyInfo = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey); //byte[] keyBytes = keyInfo.ToAsn1Object().GetEncoded(); Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder builder = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); Org.BouncyCastle.Pkcs.Pkcs12Store store = builder.Build(); store.SetCertificateEntry(friendlyName, certEntry); // create store entry store.SetKeyEntry( //keyFriendlyName friendlyName , new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(privateKey) , new Org.BouncyCastle.Pkcs.X509CertificateEntry[] { certEntry } ); byte[] pfxBytes = null; using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { // Cert is contained in store // null: no password, "": an empty passwords // note: Linux needs empty password on null... store.Save(stream, password == null ? "".ToCharArray() : password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom()); // stream.Position = 0; pfxBytes = stream.ToArray(); } // End Using stream #if WITH_MS_PFX WithMsPfx(pfxBytes, fileName, password); #else byte[] result = Org.BouncyCastle.Pkcs.Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes); // this.StoreCertificate(System.Convert.ToBase64String(result)); using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(System.IO.File.Open(fileName, System.IO.FileMode.Create))) { writer.Write(result); } // End Using writer #endif } // End Sub Create