2

C ++forWindowsで記述された既存のアプリケーションがあります。このアプリケーションは、Win32 CryptoAPIを使用して、データを暗号化/復号化するためのTripleDESセッションキーを生成します。1つのトリックの指数を使用して、セッションキーをblobとしてエクスポートします。これにより、blobを復号化された形式でどこかに保存できます。

問題は、これを.NETアプリケーション(C#)でどのように使用できるかということです。フレームワークは、CryptoAPIが実行していることの多くをカプセル化/ラップします。問題の一部は、 Microsoft Enhanced Cryptographic ProviderのTripleDESアルゴリズムが168ビット(56ビットの3キー)であるとCryptAPIが述べていることです。ただし、.NET Frameworkは、キーが192ビット(64ビットの3キー)であると述べています。どうやら、.NETフレームワークの3つの余分なバイトはパリティ用ですか?

とにかく、blobからキー部分を読み取り、それを.NETアプリケーションで使用できるようにする必要があります。現在、.NETでキーを使用しようとすると、期待した結果が得られません。復号化は惨めに失敗しています。どんな助けでも大歓迎です。

アップデート:

私はこれを解決する方法に取り組んでおり、時間内に投稿する解決策を考え出しました。ただし、それでも他の人からのフィードバックをいただければ幸いです。

4

2 に答える 2

5

はじめに

私はついに解決策を投稿しようとしています。同様のことをしている可能性のある他の人に役立つことを願っています。他の場所でこれを行うことへの言及はあまりありません。

前提条件

これを理解するには、1 つのトリックの指数を読み取る必要があります。これにより、セッション キーを BLOB (よく知られているバイト構造) にエクスポートできます。その後、このバイト ストリームを使って好きなことを行うことができますが、すべての重要な鍵が保持されています。

MSDN ドキュメントはわかりにくい

この特定の例では、Microsoft Enhanced Cryptographic Providerをトリプル DES ( CALG_3DES ) アルゴリズムと共に使用しています。最初にループに陥ったのは、キーの長さが 168 ビットで、ブロックの長さが 64 ビットであるという事実でした。鍵の長さを 168 にする方法を教えてください。56ビットの3つのキー?他のバイトはどうなりますか?

そのため、その情報を使用して、最後のバイトが実際にどのようにパリティであるかを他の場所で読み始め、何らかの理由でCryptoAPIがそれを取り除きました. 本当にそうですか?彼らがそんなことをするのはちょっとクレイジーに思えますが、OKです。

.NET でのキーの消費

TripleDESCryptoServiceProviderを使用して、ドキュメントの発言が次のことを示していることに気付きました。

このアルゴリズムは、64 ビット単位で 128 ビットから 192 ビットまでのキー長をサポートします。

では、CryptoAPI のキーの長さが 168 である場合、64 の倍数のみをサポートする .NET にそれを取得するにはどうすればよいでしょうか? したがって、API の .NET 側ではパリティが考慮されますが、CryptoAPI では考慮されません。ご想像のとおり、私は混乱していました

以上のことから、適切なパリティ情報を使用して .NET 側でキーを再構築する方法を見つけようとしています。実行可能ですが、あまり楽しくありません... そのままにしておきましょう。これをすべて配置すると、すべてが CAPITAL Fで失敗しました。

まだ私と一緒に?よかった、また馬から落ちたから。

電球と花火

ほら、MSDN の最後の情報を探していると、Win32 CryptExportKey関数に競合する部分が見つかりました。低く見て、私はこの非常に貴重な情報を見つけました:

PLAINTEXTKEYBLOB を使用する DES キー順列の場合、パリティ ビットを含む完全なキー サイズのみをエクスポートできます。次のキー サイズがサポートされています。

アルゴリズム サポートされる鍵のサイズ

CALG_DES 64 ビット

CALG_3DES_112 128 ビット

CALG_3DES 192 ビット

したがって、64 ビットの倍数であるキーをエクスポートします。ウーフー!次に、.NET 側のコードを修正します。

.NET インポート コードの微調整

CryptoAPI から BLOB としてエクスポートされたキーを含むバイト ストリームをインポートするときは、バイト オーダーに注意することが重要です。2 つの API は同じバイト順序を使用しないため、@nic-strongが示すように、実際にキーを使用する前にバイト配列を逆にすることが不可欠です。それ以外は、期待どおりに機能します。簡単に解決しました:

Array.Reverse( keyByteArray );

結論

これが誰かに役立つことを願っています。私はこれを追跡するのにあまりにも多くの時間を費やしました。さらに質問がある場合は、コメントを残してください。詳細を記入するのを手伝うことができます.

ハッピークリプト!

于 2008-12-06T01:26:28.080 に答える
1

OK、読めない最後の答えは忘れてください:) RSAキーではなく3Desキーを使用しています。

.NET、CryptoAPI、および openssl の間でキーを共有するための一連のコードに取り組みました。キー変換を行うための多くの良いサンプルコードがここに見つかりました:

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

これらの例のいくつかには 3des のものがありますが、openssl -> .NET iirc に関連していました。

また、RSAキーコードを振り返ったところ、RSAキーのすべてのキー部分(D、DP、DQ、InverseQ、Modulus、P、Q)でArray.Reverse()を使用していることに気づきました。エンディアンを変換することを推測します。最初に問題に取り組んだとき、それは自明ではなかったことを覚えています。

その一部が役立つことを願っています。幸運を。

于 2008-09-08T06:24:31.910 に答える