2014-09-30 81 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