Wie kann ich einen von Win32 CryptoAPI generierten Schlüsselblob in meiner .NET-Anwendung verwenden?

StackOverflow https://stackoverflow.com/questions/49211

Frage

Ich habe eine bestehende Anwendung, die in C++ für Windows geschrieben ist.Diese Anwendung verwendet die Win32 CryptoAPI, um einen TripleDES-Sitzungsschlüssel zum Verschlüsseln/Entschlüsseln von Daten zu generieren.Wir verwenden die Exponent eines Tricks , um den Sitzungsschlüssel als Blob zu exportieren, wodurch der Blob irgendwo in einem entschlüsselten Format gespeichert werden kann.

Die Frage ist, wie wir dies in unserer .NET-Anwendung (C#) verwenden können.Das Framework kapselt/verpackt einen Großteil dessen, was die CryptoAPI tut.Ein Teil des Problems besteht darin, dass die CryptAPI angibt, dass der TripleDES-Algorithmus für die Microsoft Enhanced Cryptographic Provider beträgt 168 Bit (3 Schlüssel mit 56 Bit).Das .NET Framework gibt jedoch an, dass ihre Schlüssel 192 Bit lang sind (3 Schlüssel mit 64 Bit).Anscheinend dienen die 3 zusätzlichen Bytes im .NET Framework der Parität?

Wie auch immer, wir müssen den Schlüsselteil aus dem Blob lesen und ihn irgendwie in unserer .NET-Anwendung verwenden können.Derzeit erhalten wir nicht die erwarteten Ergebnisse, wenn wir versuchen, den Schlüssel in .NET zu verwenden.Die Entschlüsselung scheitert kläglich.Jede Hilfe wäre sehr dankbar.

Aktualisieren:

Ich habe an Möglichkeiten gearbeitet, dieses Problem zu lösen, und habe eine Lösung gefunden, die ich rechtzeitig veröffentlichen werde.Dennoch würde ich mich über Feedback von anderen freuen.

War es hilfreich?

Lösung

Einführung

Endlich komme ich dazu, die Lösung zu veröffentlichen.Ich hoffe, es hilft anderen da draußen, die vielleicht ähnliche Dinge tun.Es gibt wirklich nicht viele Hinweise darauf, dies woanders zu tun.

Voraussetzungen

Damit vieles davon einen Sinn ergibt, ist es notwendig, das zu lesen Exponent eines Tricks, mit dem Sie einen Sitzungsschlüssel in einen Blob (eine bekannte Bytestruktur) exportieren können.Mit diesem Bytestrom kann man dann machen, was man will, aber er enthält den alles entscheidenden Schlüssel.

Die MSDN-Dokumentation ist verwirrend

In diesem speziellen Beispiel verwende ich die Microsoft Enhanced Cryptographic Provider, mit dem Triple DES (CALG_3DES) Algorithmus.Das erste, was mich aus der Fassung brachte, war die Tatsache, dass die Schlüssellänge mit 168 Bit angegeben ist, bei einer Blocklänge von 64 Bit.Wie kann die Schlüssellänge 168 sein?Drei Schlüssel mit 56 Bit?Was passiert mit dem anderen Byte?

Mit diesen Informationen begann ich an anderer Stelle zu lesen, dass das letzte Byte wirklich Parität ist und dass CryptoAPI das aus irgendeinem Grund entfernt.Ist das wirklich so?Scheint irgendwie verrückt, dass sie das tun würden, aber okay.

Verbrauch von Schlüsseln in .NET

Verwendung der TripleDESCryptoServiceProvider, Mir ist aufgefallen, dass die Bemerkungen in den Dokumenten darauf hinweisen, dass:

Dieser Algorithmus unterstützt Schlüssellängen von 128 Bit bis 192 Bit in Schritten von 64 Bit.

Wenn CryptoAPI also eine Schlüssellänge von 168 hat, wie bekomme ich das in .NET, das nur Vielfache von 64 unterstützt?Daher berücksichtigt die .NET-Seite der API die Parität, während dies bei der CryptoAPI nicht der Fall ist.Wie man sich vorstellen kann... verwirrt war ich.

Bei alledem versuche ich herauszufinden, wie ich den Schlüssel auf der .NET-Seite mit den richtigen Paritätsinformationen rekonstruieren kann.Machbar, aber nicht sehr lustig...belassen wir es einfach dabei.Nachdem ich das alles eingerichtet hatte, scheiterte alles mit einem CAPITAL F.

Immer noch bei mir?Gut, denn ich bin gerade wieder vom Pferd gefallen.

Glühbirnen und Feuerwerk

Und siehe da, während ich MSDN nach den letzten Informationen durchsuche, finde ich einen widersprüchlichen Teil in Win32 CryptExportKey Funktion.Und siehe da, ich finde diese unschätzbar wertvolle Information:

Für alle DES-Schlüsselpermutationen, die ein PLAINTEXTKEYBLOB verwenden, darf nur die vollständige Schlüsselgröße, einschließlich Paritätsbit, exportiert werden.Die folgenden Schlüsselgrößen werden unterstützt.

Vom Algorithmus unterstützte Schlüsselgröße

CALG_DES 64 Bit

CALG_3DES_112 128 Bit

CALG_3DES 192 Bit

Es wird also ein Schlüssel exportiert, der ein Vielfaches von 64 Bit ist!Juhu!Nun muss der Code auf der .NET-Seite korrigiert werden.

Optimierung des .NET-Importcodes

Beim Importieren eines Bytestreams, der einen Schlüssel enthält, der als Blob aus der CryptoAPI exportiert wurde, ist die Bytereihenfolge zu beachten.Die beiden APIs verwenden daher nicht die gleiche Bytereihenfolge @nic-strong weist darauf hin, dass das Umkehren des Byte-Arrays unbedingt erforderlich ist, bevor versucht wird, den Schlüssel tatsächlich zu verwenden.Ansonsten funktionieren die Dinge wie erwartet.Einfach gelöst:

Array.Reverse( keyByteArray );

Abschluss

Ich hoffe, das hilft jemandem da draußen.Ich habe viel zu viel Zeit damit verbracht, dem auf die Spur zu kommen.Hinterlassen Sie einen Kommentar, wenn Sie weitere Fragen haben. Ich kann versuchen, Ihnen beim Ausfüllen aller Details behilflich zu sein.

Fröhliches Krypto!

Andere Tipps

Ok, vergiss die letzte Antwort, die ich nicht lesen kann :) Sie arbeiten mit 3Des-Schlüsseln, nicht mit RSA-Schlüsseln.

Ich habe an einer Menge Code gearbeitet, um Schlüssel zwischen .NET, CryptoAPI und openSL zu teilen.Hier habe ich viele gute Beispielcodes für die Schlüsselkonvertierungen gefunden:

http://www.jensign.com/JavaScience/cryptoutils/index.html

In einigen dieser Beispiele gibt es einige 3des-Inhalte, die jedoch mit openssl -> .NET iirc zusammenhängen.

Ich habe mir auch gerade noch einmal den RSA-Schlüsselcode angesehen und dabei ist mir aufgefallen, dass ich Array.Reverse() für alle wichtigen Teile des RSA-Schlüssels (D, DP, DQ, InverseQ, Modulus, P, Q) verwende, d. h schätze, Endian zu konvertieren.Ich erinnere mich, dass das nicht offensichtlich war, als ich das Problem zum ersten Mal anging.

Ich hoffe, dass etwas davon hilft.Viel Glück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top