adwapi.dllのピンボーキング-cryptDecryptおよびcryptEncrypt関数、奇妙な問題

c# cryptoapi pinvoke smartcard
adwapi.dllのピンボーキング-cryptDecryptおよびcryptEncrypt関数、奇妙な問題

私はこの関数の奇妙な振る舞いを観察しています。暗号化する文字列には14バイトが含まれています。関数を使用してバッファの長さ= 14を送信すると、失敗します(「内部エラー」-非常に説明的で最も役立つエラーコード) 、ただし、バッファ長(およびバッファ自体)が128バイトの大きさの場合に機能します。

サイズ128バイトの配列を作成することでこの問題を克服し、プレーンテキスト(暗号化したい)から14バイトをコピーしました。

それらのバイトを復号化するとき、関数全体に128バイト配列全体を与える必要があります(今ではすべてのバイトが暗号化されており、#13-#127(これは予想される)です)。 幸いなことに、最初の14バイトは必要に応じて復号化されますが、残りは意味不明です。

着信バッファが128バイトの大きさではない場合に暗号化方法が失敗する理由、および復号化機能にも128バイト配列が必要な理由を知りたいのですが、それは何らかのパディングですか?

これは私が暗号化関数を呼び出す方法です:

System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();  // encoding type
byte[] buff = new byte[128];     // this is my buffer array, instantiated and initiated
string String2Encrypt = "Testing";      // this is the string I need encrypted
byte[] tempo = encoding.GetBytes(String2Encrypt);   // getting bytes from string
Buffer.BlockCopy(tempo, 0, buff, 0, tempo.Length);    // copying the small array into the large one
uint inputlength = Convert.ToUInt32(tempo.Length);   // getting the size of the small array


bool DidIt = UnsafeNativeMethods.CryptEncrypt(MyKey, IntPtr.Zero, 1, 0, buff, ref inputlength, outputdatalength);     // calling the function

null、3番目は「true」(データなし)、フラグなし、バッファバイト配列(128)、Testing.Lengthこの場合は7、128

これは私がそれを解読する方法です:

IntPtr UserKeyLocal = MyUserKey;     // taking an argument (MyUserKey) and "filling" the local variable, not really relevant
byte[] dataCopy = new byte[buff.Length];   // init and insta the datacopy array (128 byte)
Buffer.BlockCopy(buff, 0, dataCopy, 0, (int)buff.Length);   // copying the argument array into a local version (I used this for testing to go around another problem), irrelevant
uint locinputlength = inputlength;  // another argument made local
bool DidIT = UnsafeNativeMethods.CryptDecrypt(UserKeyLocal, IntPtr.Zero, true, 0, dataCopy, ref locinputlength);     // calling the function

結果は次のようになります。Testing?R ???? 7?q ????? $ ?? uj ?? m%?b ?? e?a?74p?)?n9 ?? w?R * O )E? i?+?> [?S ???} Ct?n?&?? b?P!?u1 ??%?JQ ??? /?mP?5wB ????

ほぼ意図したとおりに動作しますが、サブストリングのようなトリックを使用せずに、ストリングの「テスト」部分のみを取得できる必要があります。

私がやろうとしているのは(おそらく別の方法がある)これです。スマートカードからエクスポートした証明書から取得した公開キーで暗号化された「テスト」を含むバイナリ(ファイル)があります。 SmartCard(私たちはその適切なCSPを使用しています)を秘密鍵で使用して、このファイルを検証(復号化)する必要があります。 ご覧のとおり、それはほとんど動作します。

前もって感謝します。

  0  0


ベストアンサー

バッファが128バイトでなければならない理由は、ブロック暗号が使用されているためだと思います。 その場合、バッファ長はブロックサイズの倍数でなければなりません。 ブロックシッパーでは、暗号化または復号化されたデータを書き込むために、バッファーをデータのサイズよりも大きくする必要があります(length(encrypted)!= length(plaintext))。

CryptDecryptを呼び出した後、パラメーター pdwDataLen(コードでは` locInputLength`)には、復号化された実際のデータの長さが含まれます。 「dataCopy」の最初の「locInputLength」バイトのみを取得する場合、必要なものは提供されますか?

参照:http://msdn.microsoft.com/en-us/library/aa379913(VS.85).aspx http://msdn.microsoft.com/en-us/library/aa379924(VS.85).aspx

2


うん、やった! やさしい!

            byte[] buffer = new byte[locinputlength];
            Buffer.BlockCopy(dataCopy, 0, buffer, 0, (int)locinputlength);
            return buffer;

少し戻って、少し異なる視点から物を見るまで、あなたが「見ない」ものの1つです;)

0


タイトルとURLをコピーしました