2


0

RSA秘密鍵をRSACryptoServiceProviderにインポートするにはどうすればよいですか?

Win32 Crypto APIで生成されたRSA公開/秘密キーペアを.NETアプリケーションにインポートしようとしています。 キーペアを作成してエクスポートするコードは次のようになります。

// 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, ...);

基本的に、このコードは公開/秘密キーペアを暗号化されたblobとしてエクスポートしています。 SHA-1ハッシュから派生したキーを使用した暗号化に3DESアルゴリズムを使用します。

このキーを.NETにインポートしようとすると、問題が発生します。 私はアプローチしようとしました:

(1)RSACyrptoServiceProviderオブジェクトを作成し、ImportCspBlob()を呼び出します。 これにより、「bad data」というメッセージとともに例外がスローされます。プロバイダーオブジェクトには、ブロブがどのように暗号化されたかを知る方法がないため、これは驚くことではありません。 私が知る限り、これに使用するアルゴリズムとキーを伝える方法はまったくありません。

(2)PasswordDeriveBytesクラスを使用して自分でblobを手動で復号化し、復号化されたblobをImportCsbBlob()に渡します。 もう一度、例外が発生します。 今回は、メッセージは「プロバイダのバージョンが不良です」です。プロバイダーオブジェクトを作成するときに、プロバイダー名( "Microsoft Enhanced Cryptographic Provider v1.0")を手動で指定しようとしましたが、違いはありません。

これを機能させることが重要です。 何か案は?

溶液

C ++と.NETの両方で暗号化されていない公開/秘密キーペアを生成した後、Microsoft Enhanced Cryptographic Providerが実際にキーペアの最初の8バイトを暗号化しないことを発見しました。 (これは、ループの.NETラッパーをスローしていたバージョン情報である必要があります。).NET復号化コードを変更して最初の8バイトをそのままにすると、すべて正常に動作します。

このソリューションは、暗号化プロバイダーの内部実装詳細に依存するため、あまり良くありません。 残念ながら、Microsoftは復号化のアルゴリズムとキーを指定できるImportCspBlobのバージョンを提供することを怠ったため、他の方法はないと思います。

1 Answer


2


アプローチ2)では、復号化されたキーが暗号化前と同じであることを確認します。

「SHA-1ハッシュから派生したキー」がPasswordDeriveBytesのキーと一致するとは思わない