0

WinAPI CryptprotectData および CryptUnprotectData 関数を使用する Java アプリケーションを作成しようとしています。Java JNIを使​​用してこれを達成しようとしています。JNI を使用するのはこれが初めてで、データの復号化に問題があります。これを Visual Studio でデバッグしたところ、CryptUnprotectData への呼び出しが false を返し、関数が NULL を返していることがわかりました。なぜこれを行っているのかわかりません。

コードは次のとおりです。

JNIEXPORT jbyteArray JNICALL Java_Caller_Decrypt(JNIEnv * env, jobject obj, jbyteArray bytes)
{
   int len = env->GetArrayLength(bytes);
   jbyte * data = env->GetByteArrayElements(bytes,NULL);
   env->ReleaseByteArrayElements(bytes, data, 0);
   DATA_BLOB inData = {len, reinterpret_cast<unsigned char *>(data)};
   DATA_BLOB outData = {0,NULL};

   if(CryptUnprotectData(&inData,NULL,NULL,NULL,NULL,0,&outData))
   {
       LocalFree(inData.pbData);
       jbyteArray buff= env->NewByteArray(len);
       env->SetByteArrayRegion(buff,0,len,reinterpret_cast<jbyte *>(outData.pbData));
       return buff;
   }
   else
   {
       return NULL;
   }
}

関連するJavaコードは次のとおりです。

String password = "Password";
Caller c = new Caller();
System.out.println("Password");
byte[] buffer = c.Encrypt(password.getBytes());
System.out.println("Encrypted: " + new String(buffer));
System.out.println("Decrypted: " + new String(c.Decrypt(buffer)));

CryptUnprotectData 関数が false を返す理由がわかりません。C ++を使用してJavaに夢中になってから約1年が経ちました。少し錆びているので、何かを見逃した可能性があります。 JNI。どんな助け/提案も大歓迎です!

4

1 に答える 1

2

このプログラムには、いくつかの大きなメモリ管理エラーがあります。

1)呼び出しenv->ReleaseByteArrayElements(bytes, data, 0)てから、データポインタが指すメモリの内容を引き続き使用します。このメソッドはメモリを解放した可能性があり、おそらくデータの一部をメモリ管理情報で上書きします。CryptUnprotectedData()それはおそらく失敗した理由を説明しています。データのコピーを作成した後、または作成した後にenv->ReleaseByteArrayElements()電話をかける必要があります。CryptUnprotectedData()

2)LocalFree()inData.pbDataを呼び出します。これはへのポインタでありenv->GetByteArrayElements(bytes,NULL)、JNIAPIによって管理されます。また、JNI APIによってリリースする必要があります(ReleaseByteArrayElementsBTWを使用してリリースするのが早すぎました)。

3)outData.pbDataでLocalFree()を呼び出さなかった。これは、を使用してデータをコピーした後にのみ行う必要があります。SetByteArrayRegion

そうでなければ、私はWindows Crypto APIについて十分に知らないので、正しく呼び出すかどうかを確実に知ることができますが、それは私には正しいように見えます。

于 2013-02-03T02:33:25.983 に答える