Ich versuche, ein öffentliches/privates RSA-Schlüsselpaar, das mit der Win32 Crypto API erzeugt wurde, in eine .NET-Anwendung zu importieren. Der Code, der das Schlüsselpaar erstellt und exportiert, sieht ungefähr so aus:
// Abbreviated for clarity.
CryptAcquireContext(..., MS_ENHANCED_PROV, ...);
// Generate public/private key pair
CryptCreateHash(..., CALG_SHA1, ...);
CryptHashData(hash, password, ...);
CryptDeriveKey(..., CALG_3DES, hash, CRYPT_EXPORTABLE, ...);
CyrptExportKey(..., derivedKey, PRIVATEKEYBLOB, ...);
Im Grunde exportiert dieser Code das Paar aus öffentlichem und privatem Schlüssel als verschlüsselten Blob. Für die Verschlüsselung wird der 3DES-Algorithmus mit einem aus einem SHA-1-Hash abgeleiteten Schlüssel verwendet.
Wenn ich nun versuche, diesen Schlüssel in .NET zu importieren, bekomme ich Probleme. Ich habe versucht, Ansätze:
(1) Ich erstelle ein RSACyrptoServiceProvider-Objekt und rufe ImportCspBlob() auf. Dies löst eine Ausnahme mit der Meldung "bad data" aus. Das ist nicht überraschend, da das Provider-Objekt keine Möglichkeit hat, zu erfahren, wie der Blob verschlüsselt wurde. Soweit ich das beurteilen kann, gibt es keine Möglichkeit, ihm mitzuteilen, welchen Algorithmus und Schlüssel es dafür verwenden soll.
(2) Ich entschlüssele den Blob manuell selbst, indem ich die Klasse PasswordDeriveBytes verwende, und übergebe den entschlüsselten Blob an ImportCsbBlob(). Erneut erhalte ich eine Ausnahme. Diesmal lautet die Meldung "Schlechte Version des Anbieters". Ich habe versucht, den Namen des Anbieters ("Microsoft Enhanced Cryptographic Provider v1.0") bei der Erstellung des Anbieterobjekts manuell einzugeben, aber es macht keinen Unterschied.
Es ist wichtig, dass ich das hinbekomme. Irgendwelche Ideen?
LÖSUNG
Nachdem ich die unverschlüsselten öffentlichen/privaten Schlüsselpaare sowohl in C++ als auch in .NET generiert hatte, stellte ich fest, dass der Microsoft Enhanced Cryptographic Provider die ersten 8 Bytes des Schlüsselpaares nicht verschlüsselt. (Das muss an den Versionsinformationen liegen, die den .NET-Wrapper durcheinander gebracht haben). Nachdem ich meinen .NET-Entschlüsselungscode so geändert habe, dass er die ersten 8 Bytes in Ruhe lässt, funktioniert alles einwandfrei.
Diese Lösung ist nicht sehr gut, da sie von internen Implementierungsdetails des Kryptographieanbieters abhängt. Leider glaube ich nicht, dass es eine andere Möglichkeit gibt, da Microsoft es versäumt hat, eine Version von ImportCspBlob bereitzustellen, mit der Sie einen Algorithmus und Schlüssel für die Entschlüsselung angeben können.