Ich bin mittlerweile von Cryptlib auf Bouncy Castles umgestiegen, da ich merken musste, dass eine Community wichtiger ist als eine gute Doku. Auf diesem Blog werde ich verschiedene Techniken zeigen, wie man Verschlüsseln, Entschlüsseln und vor allem wie man eine CA erstellen kann. Dieser Beitrag geht vor allem um den letzten Punkt.

Vielen Dank an James Lacey von dem der Code stammt.
Im Folgenden der Code mit dem man selbst-signierte Certified Authority Zertifikate in Bouncy Castle erstellt.
Verändern kann man hierbei den Distinguished Name, das Password, das Expiration Date,... Das erstellte Zertifikat lässt sich einfach auch im Windows,Firefox,usw. importieren. Für die spätere Signierung wird ein Zertifikat benötigt, dass mit dieser CA erstellt wurde.
public void CreateCA() { SecureRandom random = new SecureRandom(); DateTime startDate = DateTime.Today; DateTime expiryDate = DateTime.MaxValue; // Set whatever expiration date you want BigInteger serialNumber = new BigInteger(1, BitConverter.GetBytes(DateTime.Now.Ticks)); RsaKeyPairGenerator generator = new RsaKeyPairGenerator(); KeyGenerationParameters genParam = new KeyGenerationParameters(random, 2048); generator.Init(genParam); AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair(); X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); X509Name dnName = new X509Name(“CN=My CA Certificate”); certGen.SetSerialNumber(serialNumber); certGen.SetIssuerDN(dnName); certGen.SetNotBefore(startDate); certGen.SetNotAfter(expiryDate); certGen.SetSubjectDN(dnName); certGen.SetPublicKey(keyPair.Public); certGen.SetSignatureAlgorithm("SHA1withRSA"); X509Certificate cert = certGen.Generate(keyPair.Private); Pkcs12Store pkcs = new Pkcs12Store(); string alias = BitConverter.ToString(BitConverter.GetBytes(random.NextLong())); pkcs.SetKeyEntry(alias, new AsymmetricKeyEntry(keyPair.Private), new X509CertificateEntry[] { new X509CertificateEntry(cert) }); Stream stream; // Use a MemoryStream or FileStream as appropriate for what you want to do. pkcs.Save(stream, “My CA Password”.ToCharArray(), random); }
Jetzt fehlt nur noch eine Funktion um das Ganze zu benutzen um Zertifikate zu erstellen die signiert sind. Eingestellt werden können wie in der vorigen Funktion die gleichen Parameter. Um das ganze zu speichern kann man das per FileStream aufs Dateisystem packen.
public void CreateCertificateWithCA(X509Certificate caCert, AsymmetricKeyParameter caKey)
{
SecureRandom random = new SecureRandom();
DateTime startDate = DateTime.Today;
DateTime expiryDate = DateTime.Today.AddYears(1); // Set whatever expiration date you want
BigInteger serialNumber = new BigInteger(1, BitConverter.GetBytes(DateTime.Now.Ticks));
RsaKeyPairGenerator generator = new RsaKeyPairGenerator();
KeyGenerationParameters genParam = new KeyGenerationParameters(random, 2048);
generator.Init(genParam);
AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X509Name dnName = new X509Name(“CN=My Certificate”);
certGen.SetSerialNumber(serialNumber);
certGen.SetIssuerDN(caCert.IssuerDN);
certGen.SetNotBefore(startDate);
certGen.SetNotAfter(expiryDate);
certGen.SetSubjectDN(dnName);
certGen.SetPublicKey(keyPair.Public);
certGen.SetSignatureAlgorithm("SHA1withRSA");
certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, new AuthorityKeyIdentifierStructure(caCert));
certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, true, new SubjectKeyIdentifierStructure(keyPair.Public));
certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));
X509Certificate cert = certGen.Generate(caKey);
Pkcs12Store pk12 = new Pkcs12Store();
string alias = BitConverter.ToString(BitConverter.GetBytes(random.NextLong()));
pk12.SetKeyEntry(alias, new AsymmetricKeyEntry(keyPair.Private), new X509CertificateEntry[] { new X509CertificateEntry(cert) });
Stream stream; // Use a MemoryStream or FileStream as appropriate for what you want to do.
pk12.Save(stream, “My Password”.ToCharArray(), random);
}
Ich benutze die funktionen, falls also Fragen bestehen einfach nen Kommentar schreiben.
Viele Grüße,
Benjamin Peters-Rumpf
Hallo Benjamin,
der Code sieht gut aus, funktioniert in meiner VB.Net Portierung aber leider nicht richtig. Wenn ich die Zertifikate per FileStream schreibe und installieren will erhalte ich immer die Meldung: “Diese Datei ist für folgende Verwendung ungültig: Sicherheitszertifikat”.
Vielleicht haben sie ja eine Ahnung, was hier falsch läuft?
Mfg Karsten
Hier mal der übersetzte Code:
Dim generator As New Crypto.Generators.RsaKeyPairGenerator
Dim genParam As New Crypto.KeyGenerationParameters(random, 2048)
generator.Init(genParam)
Dim keyPair As Crypto.AsymmetricCipherKeyPair = generator.GenerateKeyPair
Dim certGen As New X509.X509V1CertificateGenerator
Dim dnName As New Asn1.X509.X509Name(“CN=example.com”)
certGen.SetSerialNumber(serialNumber)
certGen.SetIssuerDN(dnName) certGen.SetNotBefore(startDate) certGen.SetNotAfter(expiryDate) certGen.SetSubjectDN(dnName) certGen.SetPublicKey(keyPair.Public)
certGen.SetSignatureAlgorithm(“SHA1withRSA”)
Dim cert As X509.X509Certificate = certGen.Generate(keyPair.Private)
Dim pkcs As New Pkcs.Pkcs12Store
Dim alia As String = BitConverter.ToString(BitConverter.GetBytes(random.NextLong))
pkcs.SetKeyEntry(alia, New Pkcs.AsymmetricKeyEntry(keyPair.Private), New Pkcs.X509CertificateEntry() {New Pkcs.X509CertificateEntry(cert)})
Using fs As New System.IO.FileStream(fileName, IO.FileMode.Create)
‘pkcs.Save(fs, New Char() {}, random)
pkcs.Save(fs, “Abcd1324″.ToCharArray, random)
End Using
Mein Fehler.
Die resultierende Datei muss natürlich die Dateiendung *.pfx haben – dann klappts auch mit dem Zertifikat.
Hallo Benjamin,
wie kann ich
CreateCertificateWithCA(X509Certificate caCert, AsymmetricKeyParameter caKey)
aufrufen ohne das ich vorher CreateCA() aufrufe.
Es get im die Parameter caCert und caKey welche ich dann aus einem bestehenden CA-Zertifikate entnehmen möchte.
Hallo Sven,
du kannst da ein ganz normales X509 Zertifikat laden und dann dieses übergeben. Setze als Parameter einfach dein bestehendes Zertifikat.
Grüße,
Benjamin
Leider steht nirgends wie ich mit BouncyCastle ein Zertifikat lade bzw. auswählen kann, oder von System.Security nach BouncyCastle konvertiere.
Der Wert vom Typ “System.Security.Cryptography.AsymmetricAlgorithm” kann nicht in “Org.BouncyCastle.Crypto.AsymmetricKeyParameter” konvertiert werden.