2014-09-30 122 views
1

我在JNI中轉換時遇到問題。JNI - 從字節傳輸到字節,從字節到字符串問題

在C++中,我使用AES(Library CryptoPP)創建了一些密碼。我將結果轉換爲字符串並將其返回。這是如何獲得字符串的代碼如下所示:

JNIEXPORT jbyteArray JNICALL Java_com_example_androidake_MutualAuthenticateChip_prepareEncryptionCPP 
(JNIEnv *env, jobject thisObj, jboolean hmm, jboolean jinit) { 

    string encryption= mac->EncryptCertKey(); 

    jbyteArray returns = env->NewByteArray(encryption.size()); 
    env->SetByteArrayRegion(returns, 0, encryption.length(), (jbyte*) encryption.c_str()); 

    return returns; 
}; 

上面的字符串正在轉換爲返回的jbyteArray。首先,我想用

env->NewStringUTF(encryption.c_str()); 

剛剛返回的字符串,但應用程序已經崩潰。我認爲這是由變量'加密'的內容引起的。我使用env-> NewStringUTF(encryption.c_str());在其他函數中,返回的字符串只是一個數字或類似的東西。

然後在Java中,我從字節做轉換爲字符串:

byte[] cipher = mac_A.prepareEncryptionCPP(true, true); 
string cipher_str = new String(cipher); 

而且我再次把這個字符串到C++對象和比較舊的密碼與被從Java發送密碼:

//Java 
boolean result = mac_A.compareEncryption(true, cipher); 
//JNI 
JNIEXPORT jboolean JNICALL Java_com_example_androidake_MutualAuthenticateChip_compareEncryption 
    (JNIEnv * env, jobject thisObj, jboolean jinit, jstring cipher){ 
    bool init = jinit; 
    bool result; 

    jsize length = env->GetStringUTFLength(cipher); 
    const char *inCStr_ek = env->GetStringUTFChars(cipher, 0); 
    string s(inCStr_ek, length); 

    result = mac->CompareCipher(s); 

    env->ReleaseStringUTFChars(cipher, inCStr_ek); 
    return result; 
}; 

在C++比較:

bool MyClass::CompareCipher(std::string cipher_2){ 
    if(cipher == cipher_2){ 
     return true; 
    }else{ 
     return false; 
    } 
} 

,它始終返回false。我不知道我做錯了什麼。我甚至將這個密碼從Java發送到C++,並將其帶回到Java,並且這些字符串是平等的,但在C++端不是。

在Java端代碼
+0

「我正在將[加密]結果轉換爲字符串。」這已經是一個錯誤,除非你先進行十六進制編碼或base64編碼。字符串不是二進制數據的容器。 – EJP 2014-09-30 23:22:43

回答

1

你有

byte[] cipher = mac_A.prepareEncryptionCPP(true, true); 
boolean result = mac_A.compareEncryption(true, cipher); 

compareEncryption JNI功能與定義的jstring,不jbytearray。

因此,從JNI方面,你發送一個字節數組到Java,並從Java端發回相同的字節數組本地端(但在調用中使用jstring),但然後你使用env->GetStringUTFChars(cipher, 0)轉換該字節數組到一個修改後的UTF-8字符串中,所以它在技術上不再是同一個字節數組。

如果你需要字符串在java端進行轉換,只需在jni和java之間使用相同的普通字節數組。 Android JNI中的See this for string encoding issues

+0

對不起,這是我在這裏重寫代碼的錯誤。我使用布爾結果= mac_A.compareEncryption(true,cipher_str);我會明天檢查你的鏈接。 – user1683637 2014-10-01 21:37:53

+0

該字符串正由'GetStringUTFChars'轉換爲modified-utf8。我會考慮從java端發送jbytearray,所以你在jni端有相同的字節數組進行比較。 – ashoke 2014-10-01 21:46:11

+0

非常感謝。當我發送字節到比較函數時,一切正常。我將這個字節數組更改爲String Base64,然後將此字符串返回到字節數組,然後將此字節數組發送到比較函數(這僅用於測試),但我解決了這個問題。再次感謝。 – user1683637 2014-10-04 18:31:22