Sry bout die lange Antwort.
Ja, Sie können bouncycastle verwenden, um ein Zertifikat aus einem pfx zu extrahieren.
var pkcs = new Pkcs12Store(File.Open("path.pfx", FileMode.Open), "password".ToCharArray());
pkcs.Aliases // is a list of certificate names that are in the pfx;
pkcs.GetCertificate(alias); // gets a certificate from the pfx
Wir verwenden einen sehr ähnlichen Ansatz, aber wir senden das Zertifikat ohne den privaten Schlüssel in PEM zurück, da es keine "Geheimnisse" enthält.
So stellen Sie einen Antrag auf Signierung eines Zertifikats:
//generate a privatekey and public key
RsaKeyPairGenerator rkpg1 = new RsaKeyPairGenerator();
rkpg1.Init(new KeyGenerationParameters(new SecureRandom(), Keystrength));
AsymmetricCipherKeyPair ackp1 = rkpg1.GenerateKeyPair();
RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)ackp1.Private;
RsaKeyParameters publicKey = (RsaKeyParameters)ackp1.Public;
X509Name comonname = new X509Name (cname);
Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest ("SHA1WITHRSA", comonname, publicKey, null, privateKey);
csr.Verify ();
StringBuilder sb = new StringBuilder();
PemWriter pw = new PemWriter (new StringWriter (sb));
pw.WriteObject (csr);
pw.Writer.Flush ();
var pemstring = sb.ToString ();
Dies geschieht auf der Serverseite beim Signieren der Zertifikatsignierungsanforderung:
Soweit ich weiß, kann das Root-Zertifikat jedes Zertifikat sein, für das Sie einen privaten Schlüssel besitzen. Und wenn Sie es in einer anderen Anwendung wie einem Browser verwenden wollen, muss es in den Zertifikatspeicher "Vertrauenswürdige Stammzertifizierungsstellen" eingefügt werden, wenn es ein selbstsigniertes Zertifikat ist, oder "Vertrauenswürdige Zwischenzertifizierungsstellen", wenn es auf dem Client-Computer nicht selbstsigniert ist. sans der Piratenschlüssel vom Kurs ab.
Ein Zertifikat mit einem privaten Schlüssel ist an dem kleinen Schlüssel zu erkennen, der dem Symbol hinzugefügt wurde (siehe hier);
//rootCert contains the rootcertificate in bouncycastle format
var pemstring = "a string containing the PEM";
PemReader pr = new PemReader (new StringReader (pemstring));
Pkcs10CertificationRequest csr = (Pkcs10CertificationRequest)pr.ReadObject ();
X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();
certgen.SetSubjectDN(csr.GetCertificationRequestInfo().Subject);
certgen.SetIssuerDN(rootCert.SubjectDN);
certgen.SetPublicKey(csr.GetPublicKey());
certgen.SetSignatureAlgorithm(csr.SignatureAlgorithm.ObjectID.Id);
certgen.SetNotAfter(validThrough); //a datetime object
certgen.SetNotBefore(validFrom); //a datetime object
certgen.SetSerialNumber(serialNumber); //a biginteger
X509Certificate clientcert = certgen.Generate(rootPrivateKey);
//to send the certificate without the private key to the client you'll have to
//convert it to PEM:
StringBuilder sb = new StringBuilder();
PemWriter pw = new PemWriter (new StringWriter (sb));
pw.WriteObject (clientcert);
pw.Writer.Flush ();
var pemstring = sb.ToString ();
//to make it a .net certificate use:
X509Certificate2 netcert = DotNetUtilities.ToX509Certificate (clientcert);
Das Client-Zertifikat enthält derzeit KEINEN privaten Schlüssel. Das geschieht auf der Client-Seite wieder so:
//where pemstring contains the certificate in a PEMstring like shown above.
//and privateKey is the one we had in the first part over at the client.
PemReader pr = new PemReader(new StringReader(pemstring));
X509Certificate2 cert = DotNetUtilities.ToX509Certificate((Bouncy.X509Certificate)pr.ReadObject());
CspParameters cparms = new CspParameters
{
CryptoKeySecurity = new CryptoKeySecurity(),
Flags = CspProviderFlags.UseMachineKeyStore
};
RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider(cparms);
RSAParameters parms = new RSAParameters
{
Modulus = privateKey.Modulus.ToByteArrayUnsigned (),
P = privateKey.P.ToByteArrayUnsigned (),
Q = privateKey.Q.ToByteArrayUnsigned (),
DP = privateKey.DP.ToByteArrayUnsigned (),
DQ = privateKey.DQ.ToByteArrayUnsigned (),
InverseQ = privateKey.QInv.ToByteArrayUnsigned (),
D = privateKey.Exponent.ToByteArrayUnsigned (),
Exponent = privateKey.PublicExponent.ToByteArrayUnsigned ()
};
rcsp.ImportParameters(parms);
netcert.PrivateKey = rcsp;