CMS-Signierung in .NET mit Zertifikatskette nicht im lokalen vertrauenswürdigen Zertifikatspeicher

8

Ich habe X509-Zertifikate, die im Netzwerk gespeichert sind. Ich kann die Kette aus dem Windows-Zertifikatspeicher lesen. Ich muss einige Daten unterschreiben und eine Kette in die Signatur einfügen, um es später zu validieren.

Das Problem ist, dass ich keine Möglichkeit finde, eine Zertifikatskette in den CsmSigner zu legen. Ich habe gelesen, dass es Zertifikat von Konstruktor Parameter und versucht, eine Kette mit X509Chain.Build zu bauen. Es ignoriert Zertifikatslistenwerte und schlägt (offensichtlich) fehl, da kein Zertifikat im lokalen Windows-Zertifikatsspeicher gefunden werden kann.

Hier finden Sie meinen Testcode (funktioniert nur, wenn Zertifikate lokal im Windows-Cert-Store gespeichert wurden)

%Vor%

Gibt es eine Möglichkeit, es ohne das Hochladen von Zertifikaten in dem lokalen Speicher zu funktionieren? Sollte ich einen alternativen Unterzeichner verwenden?

Ich kann versuchen, Zertifikate in den Store hochzuladen, aber die Probleme sind das

  • Ich muss Zertifikate hinzufügen und entfernen (Berechtigungen müssen erteilt werden)

  • Es gibt mehrere Prozesse, die die Signatur anwenden, sodass eine prozessübergreifende Synchronisation hinzugefügt werden muss.

  • Das möchte ich nicht tun.

oleksa 29.12.2014, 11:15
quelle

3 Antworten

4

Beispiel CMS Signing mit BouncyCastle für .NET

könnten Sie verwenden die BouncyCastle Krypto-Bibliothek für .NET, die ihre eigenen X509-Zertifikat und CMS Unterzeichnung Maschinen enthält. Viele der Beispiele und Dokumentationen im Internet sind für Java, als BouncyCastle eine Java-Bibliothek zuerst war. Ich habe gebrauchte die Antwort auf diese Frage Stackoverflow als Startpunkt für das Laden des Zertifikats und Schlüssels und fügte die CMS-Signierung hinzu. Möglicherweise müssen Sie Parameter optimieren, um die gewünschten Ergebnisse für Ihren Anwendungsfall zu erzielen.

Ich habe die Unterzeichnung Funktion wie das Ihre sucht etwa gemacht, aber beachten Sie die privaten Schlüssel nun ein eigener Parameter ist.

%Vor%

.NET CMS (Quick-fix mit dem Rest der Kette von der Unterzeichnung weggelassen)

Ich kann Ihr Problem mit einem Zertifikat reproduzieren, dessen Stamm nicht im vertrauenswürdigen Zertifikatspeicher enthalten ist, und bestätigen, dass beim Hinzufügen der Zertifikatkette zur cmsSigner / signedCms Certificates -Aktion der A certificate chain could not be built to a trusted root authority -Fehler nicht vermieden wird.

Sie können erfolgreich signieren, indem Sie cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;

setzen

Wenn Sie dies tun, erhalten Sie den Rest der Kette in der Signatur nicht. Das ist wahrscheinlich nicht das, was du willst.

Nebenbei, in Ihrem Beispiel verwenden Sie X509Certificate für das Array von Zertifikaten in der Kette, aber übergeben sie an ein X509Certificate2Collection (beachten Sie die "2" darin). X509Certificate2 leitet sich von X509Certificate ab, aber wenn es nicht tatsächlich ein X509Certificate2 ist, das Sie in eine dieser Sammlungen einfügen, erhalten Sie einen Umwandlungsfehler, wenn etwas über die Sammlung iteriert wird (Sie bekommen beim Hinzufügen keine Fehlermeldung) ein Zertifikat vom falschen Typ, da X509Certificate2Collection auch von X509CertificateCollection abgeleitet ist und seine Add-Methoden erbt.)

    
softwariness 26.01.2015, 01:56
quelle
3

Hinzufügen von Beispielcode, der eine freistehende PKCS7-Signatur mithilfe von BouncyCastle (dank der Flexibilität) ohne Zertifikatspeicher erstellt.

Es verwendet .net X509Certificate2-Instanzen als Eingabeparameter. Das erste Zertifikat in der Sammlung muss mit dem privaten Schlüssel verknüpft werden, um Daten zu signieren.

Ich möchte auch darauf hinweisen, dass es nicht möglich ist, den privaten Schlüssel zu lesen, der mit dem Zertifikat aus dem entfernten Windows-Zertifikatspeicher verknüpft ist, indem Sie die Eigenschaft .net X509Certificate2.Private verwenden. Standardmäßig wird der private Schlüssel nicht mit dem Zertifikat unter Verwendung von X509Store (@ "\ remotemachine \ MY", StoreLocation.LocalMachine) geladen, und wenn die Eigenschaft X509Certificate2.PrivateKey auf dem lokalen Computer aufgerufen wird, schlägt der Fehler "Keyset existiert nicht" fehl.

%Vor%     
oleksa 29.01.2015 14:51
quelle
2

Um es klar zu sagen, ich bin kein Sicherheits- oder Kryptografieexperte .. aber nach meinem Wissen, damit der Empfänger die Signatur validieren kann, das Stammzertifikat in der Zertifikatskette, die Sie zum Signieren verwendet haben, Muss bereits ein vertrauenswürdiger Stamm für den Empfänger sein.

Wenn der Empfänger das Stammzertifikat nicht bereits in seinem Speicher hat und als vertrauenswürdiger Stamm markiert ist, dann spielt es keine Rolle, wie Sie die Daten signieren. Und das ist Absicht.

Weitere Informationen finden Sie unter Vertrauenskette

Daher ist die einzige wirkliche Lösung für Ihr Problem, die ich sehe, sicherzustellen, dass das Stammzertifikat als vertrauenswürdiger Stamm auf beiden Seiten bereitgestellt wird ... Normalerweise wird dies von einem Zertifizierungsstelle .

Unternehmensanwendungsszenario - Typischerweise würde in einem Unternehmen eine Gruppe in der IT-Abteilung (die Zugriff auf alle Maschinen in der Domäne haben - wie Domain-Administratoren) dieses Szenario aktivieren, indem sie jeden Computer in der Domäne sicherstellt Hat ein Stammzertifikat, das dieser Gruppe gehört und auf jedem Computer als vertrauenswürdiger Stamm angezeigt wird, und ein Anwendungsentwickler im Unternehmen normalerweise ein neues Zertifikat zur Verwendung mit seiner Anwendung anfordert, wobei die Vertrauenskette zum Stammzertifikat zurückreicht, das bereits an alle verteilt wurde Maschinen in der Domäne.

Sie haben in Ihrer Firma eine Kontaktperson für diese Gruppe gefunden und lassen ein Zertifikat erstellen, das Sie für die Unterschrift verwenden können.

Internetanwendungsszenario - Es gibt etablierte Zertifizierungsstellen, die Eigentümer ihrer Stammzertifikate sind und mit Betriebssystemanbietern zusammenarbeiten, um sicherzustellen, dass sich ihre Stammzertifikate im vertrauenswürdigen Speicher befinden es sind Kunden. (Ein Grund, warum die Verwendung von Raubkopien schädlich sein kann. Es geht nicht nur um Viren / Malware.). Aus diesem Grund kann die Signatur, wenn Sie ein von VeriSign ausgestelltes Zertifikat zum Signieren der Daten verwenden, von den meisten anderen Rechnern der Welt validiert werden.

    
Vikas Gupta 04.01.2015 19:44
quelle