-2

JNIでこの関数を実装する方法は?

public byte[] decrypt(byte[] enc) throws Exception{
    Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    SecretKeySpec    myKey = new SecretKeySpec(key, "DESede");
    IvParameterSpec ivspec = new IvParameterSpec(initializationVector);
    c3des.init(Cipher.DECRYPT_MODE, myKey, ivspec);
    byte[] cipherText = c3des.doFinal(enc);
    return cipherText;
}

ほとんどすべてのメソッドを書きましたが、最後の 2 行に問題があります。

jbyteArray Java_MainActivity_decrypt(JNIEnv* env, jobject context,jbyteArray key, jbyteArray iv, jbyteArray enc) {


   //Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
   jclass cl = (*env)->FindClass(env,"javax/crypto/Cipher");
   jmethodID MID = (*env)->GetStaticMethodID(env,cl, "getInstance", "(Ljava/lang/String;)Ljavax/crypto/Cipher;");
   jstring s = (*env)->NewStringUTF(env,"DESede/CBC/PKCS5Padding");
   jobject c3des = (*env)->CallStaticObjectMethod(env,cl, MID, s);

   //SecretKeySpec    myKey = new SecretKeySpec(key, "DESede");
   jclass cl1 = (*env)->FindClass(env, "javax/crypto/spec/SecretKeySpec");
   jclass constructor1 = (*env)->GetMethodID(env, cl1, "<init>", "([BLjava/lang/String;)V");
   jstring s1 = (*env)->NewStringUTF(env,"DESede");
   jobject myKey = (*env)->NewObject(env, cl1, constructor1, key, s1);

   //IvParameterSpec ivspec = new IvParameterSpec(initializationVector);
   jclass cl2 = (*env)->FindClass(env, "javax/crypto/spec/IvParameterSpec");
   jclass constructor2 = (*env)->GetMethodID(env, cl2, "<init>", "([B)V");
   jobject ivspec = (*env)->NewObject(env, cl2, constructor2, iv);

   //c3des.init(Cipher.DECRYPT_MODE, myKey, ivspec);
   jmethodID mid_int = (*env)->GetMethodID(env, cl, "init","(ILjava/security/Key;Ljava/security/AlgorithmParameters;)V");
   jfieldID field_dec_id = (*env)->GetStaticFieldID(env, cl, "DECRYPT_MODE","I");
   jint field_dec = (*env)->GetStaticIntField(env, cl, field_dec_id);
   (*env)->CallVoidMethod(env,c3des,mid_int,field_dec,myKey,ivspec); //<--app crash at this line

   return;
}

アプリのクラッシュ

(*env)->CallVoidMethod(env,c3des,mid_int,field_dec,myKey,ivspec);

myKey と ivspec は問題ありません。それらを返して Java で復号化できます。

Cipher c3des = Cipher.getInstance("DESede/CBC/NoPadding");
c3des.init(Cipher.DECRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(enc);

前もって感謝します

4

1 に答える 1

1

Android JNI のヒントページ (つまり、 )の手順に従って、拡張 JNI チェックを有効にする必要がありますadb shell setprop debug.checkjni 1。または、CheckJNI 機能が有効になっているエミュレーターでコードを実行することもできます。通常、これを有効にした後、logcat の出力を見ると、JNI 呼び出しがクラッシュしている正確な理由がわかります。

また、Java メソッドの呼び出しの間に次のことを行う必要があります。

if (env->ExceptionCheck()) {
    // オプションで、ここに何かを記録します。
    NULL を返します。
}

この特定のケースでは、 に対して間違った関数プロトタイプを使用しているようですCipher#initIvParameterSpecは のインスタンスでAlgorithmParameterSpecあり、 ではないため、代わりAlgorithmParametersにプロトタイプを使用する必要があります。(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V

于 2013-05-26T18:45:59.290 に答える