Ist es möglich, programmgesteuert generieren eines X. 509-Zertifikat mit nur C#?
Sind wir zu erzeugen versuchen ein X509-Zertifikat (inklusive privatem Schlüssel) Programmierung mit Hilfe von C# und die BouncyCastle Bibliothek. Wir haben versucht, mit einigen der code von dieses Beispiel von Felix Kollmann aber der private Teil des Schlüssels des Zertifikats, wird null zurückgegeben. Code-und unit-Tests sind wie folgt:
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace MyApp
{
public class CertificateGenerator
{
///<summary>
///
///</summary>
///<remarks>Based on <see cref="http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx"/></remarks>
///<param name="subjectName"></param>
///<returns></returns>
public static byte[] GenerateCertificate(string subjectName)
{
var kpgen = new RsaKeyPairGenerator();
kpgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var kp = kpgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var certName = new X509Name("CN=" + subjectName);
var serialNo = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(serialNo);
gen.SetSubjectDN(certName);
gen.SetIssuerDN(certName);
gen.SetNotAfter(DateTime.Now.AddYears(100));
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(kp.Public);
gen.AddExtension(
X509Extensions.AuthorityKeyIdentifier.Id,
false,
new AuthorityKeyIdentifier(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public),
new GeneralNames(new GeneralName(certName)),
serialNo));
gen.AddExtension(
X509Extensions.ExtendedKeyUsage.Id,
false,
new ExtendedKeyUsage(new ArrayList() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") }));
var newCert = gen.Generate(kp.Private);
return DotNetUtilities.ToX509Certificate(newCert).Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "password");
}
}
}
Unit-test:
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyApp
{
[TestClass]
public class CertificateGeneratorTests
{
[TestMethod]
public void GenerateCertificate_Test_ValidCertificate()
{
//Arrange
string subjectName = "test";
//Act
byte[] actual = CertificateGenerator.GenerateCertificate(subjectName);
//Assert
var cert = new X509Certificate2(actual, "password");
Assert.AreEqual("CN=" + subjectName, cert.Subject);
Assert.IsInstanceOfType(cert.PrivateKey, typeof(RSACryptoServiceProvider));
}
}
}
InformationsquelleAutor Tom Robinson | 2010-09-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur um zu klären, ein X. 509-Zertifikat enthält nicht den privaten Schlüssel. Das Wort Zertifikat wird manchmal missbraucht, stellen die Kombination von Zertifikat und den privaten Schlüssel, aber Sie sind zwei verschiedene Entitäten. Der springende Punkt bei der Verwendung von Zertifikaten zu senden, die Sie mehr oder weniger offen, ohne dass der private Schlüssel, der geheim gehalten werden muss. Ein
X509Certificate2
Objekt kann ein privater Schlüssel zugeordnet (über seinePrivateKey
- Eigenschaft), aber das ist nur eine Bequemlichkeit, die als Teil der Gestaltung dieser Klasse.In Ihrem ersten BouncyCastle code-Beispiel
newCert
ist wirklich nur das Zertifikat undDotNetUtilities.ToX509Certificate(newCert)
ist gebaut aus dem Zertifikat nur.Wenn man bedenkt, dass die PKCS#12-format erfordert das Vorhandensein eines private key, ich bin ziemlich überrascht, dass der folgende Teil noch funktioniert (wenn man bedenkt, Sie fordern es auf ein Zertifikat kann nicht wissen, den privaten Schlüssel):
(
gen.Generate(kp.Private)
signiert das Zertifikat mit dem privaten Schlüssel, aber keine privaten Schlüssel im Zertifikat, das würde keinen Sinn machen.)Wenn Sie möchten, dass Ihre Methode zurückgegeben, die sowohl das Zertifikat und den privaten Schlüssel können Sie entweder:
X509Certificate2
Objekt, in dem Sie initialisiert haben diePrivateKey
Eigenschaftbyte[]
Inhalt (als wenn es wurde eine Datei). Schritt 3 in dem link, den du geschickt hast (Spiegel) erklärt, wie man eine PKCS#12-speichern.Rücksendung der
byte[]
(DER) Struktur für die X. 509 Zertifikat enthält nicht den privaten Schlüssel.Wenn Ihr Hauptanliegen ist (laut deinem test der Fall), um zu überprüfen, dass das Zertifikat wurde gebaut aus einem RSA-Schlüssel-paar, können Sie überprüfen Sie den Typ des öffentlichen Schlüssels statt.
Den link für die Schritt 3 scheint down zu sein. Zum Glück archive.org noch hat den Inhalt:
fühlen Sie sich frei zu Bearbeiten, meine Antwort, und ersetzen Sie Sie, sollten Sie ein paar Punkte zu.
Ich denke, dieses Thema/Frage ist groß, denn wenn Sie wollen, aktivieren Sie die message-Sicherheit in WCF und wollen Sie nicht oder können die Bereitstellung der certifcates auf die Maschinen, die Schaffung von "in-memory-one-time-certitificates" wäre eine großartige Möglichkeit, um Sicherheit zu aktivieren, ohne die Notwendigkeit von root-certifcates. Hier ist ein link zu jemandem, der nutzt die Windows-API zum erstellen von Zertifikaten. Ich habe nicht versucht, aber vielleicht hilft es ja jemandem, seine Ziele zu erreichen: vtrifonov.com/2012/10/...
so signieren Sie ein Zertifikat mit Hüpfburg oder machen Sie CA-signierte Zertifikate mit Hüpfburg
InformationsquelleAutor Bruno
Merke ich, dies ist eine alte post, aber ich fand diese ausgezeichnete Artikel, die durch den Prozess gehen:
Mit Hüpfburg aus .NET
Erste Sicherheitswarnung für den link..
Ich habe aktualisiert den link.
Dies ist ein gutes und funktionsfähiges Beispiel. Es ist jedoch überholt. Einige Funktionen wie
SetSignatureAlgorithm()
zeigen eine deprecation-Warnung. Hat jemand hier ein update möglich?InformationsquelleAutor haymansfield