2 Stimmen

Verwendung einer PFX-Datei X509 für die Verschlüsselung/Entschlüsselung

Ich habe eine pfx-Datei, die für Testzwecke gedacht ist und keine besonderen Sicherheitsvorkehrungen enthält.

Ich muss diese Datei verwenden, um eine XML-Datei zu verschlüsseln. Das Szenario ist, dass ich eine Passwort-Zip-Datei an einen Kunden senden muss, zusammen mit einer Metadaten-Datei, die sich auf die Zip-Datei bezieht. Die Zip-Datei enthält eine Datei zur Aktualisierung einer Softwareinstallation. Zuerst dachte ich, ich würde die Zip-Datei selbst verschlüsseln. Aber dann wurde beschlossen, dass es mit einem einfachen Passwort geschützt und auf eine Website (ASP.NET) beim Kunden hochgeladen wird. Der Kunde wird auch eine Metadaten-Datei hochladen, die mit dem gezippten Update geliefert wird. Diese Metadaten-Datei wird Dinge wie Client-Kennung, MAC-Adresse, MD5-Hash der Update-Zip-Datei usw. enthalten. Ich muss diese Metadaten-Datei vor dem Senden verschlüsseln und entschlüsseln, sobald der Kunde sowohl die ZIP- als auch die Metadaten-Datei hochgeladen hat. Nach der Entschlüsselung werde ich versuchen, den Client, die aktuelle Installation und den Patch selbst zu überprüfen.

Der PFX wird für mich generiert.

  • Was muss ich aus der PFX-Datei extrahieren?
  • Ich kann BouncyCastle hier verwenden.
  • Die Idee war, dass der Kunde nach der Installation der Software auf seiner Seite eine X509-Zertifikatsanforderung erzeugt. Dabei werden zwei Dinge erzeugt: die Anforderung und ein privater Schlüssel. Der Kunde behält den privaten Schlüssel und schickt uns die Anforderung. Wir überprüfen den Kunden (Zahlung und alles andere), generieren ein Zertifikat für ihn und senden es ihm per E-Mail zurück (das PFX). Er importiert es dann, um die Funktionen der Software freizuschalten und kann gezippte Updates und andere Dinge erhalten.

Die Frage ist ein bisschen eine komplette Lösung Nachfrage wie, aber ich bin vor eine echte harte Zeit, dann kommt es zum Signieren mit X509. Ich bin auf BouncyCastle docs gerade jetzt suchen.

Vielen Dank für die Lektüre. Jede Hilfe wird geschätzt werden.

4voto

albertjan Punkte 7531

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); self signed certificate with comonname localhost

//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;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X