2011-08-03 32 views
0

我正在做一個JNI包裝從openssl調用AES_ecb_encrypt函數。JNI包裝openssl AES_ecb_encrypt不工作

的包裝看起來是這樣的:

#include "aes.h" 
#include <jni.h> 
#include <string.h> 


jbyteArray 
Java_com_package_AESDecryptionFilterInputStream_encrypt(JNIEnv* env, 
              jobject this, 
              jbyte* data, 
              jbyte* userkey, 
              jint length, 
              jint mode) 
{ 
    const unsigned char* indata = (unsigned char*)data; 
    const unsigned char* ukey = (unsigned char*)userkey; 
    unsigned char *outdata = NULL; 
    outdata = malloc(length); 

    AES_KEY key; 
    memset(&key, 0, sizeof(AES_KEY)); 

    if(mode == AES_ENCRYPT) 
     AES_set_encrypt_key(ukey, 128, &key); 
    else 
     AES_set_decrypt_key(ukey, 128, &key); 

    AES_ecb_encrypt(indata, outdata, &key, mode); 

    jbyteArray bArray = (*env)->NewByteArray(env, length); 
    jboolean isCopy; 
    void *decrypteddata = (*env)->GetPrimitiveArrayCritical(env, (jarray)bArray, &isCopy); 
    memcpy(decrypteddata, outdata, length); 

    (*env)->ReleasePrimitiveArrayCritical(env, bArray, decrypteddata, 0); 

    return bArray; 
} 

,但是,當我把它從Java代碼進行加密和解密,然後一個字符串,結果是不正確的。

我聲明瞭該程序是這樣的:

 static { 
     System.loadLibrary("aes_ecb"); 
    } 

    public native byte[] encrypt(byte[] data, byte[] userkey, int length, int mode); 

我打電話這樣說:

 byte[] dec = "".getBytes(); 
     byte[] enc = encrypt(dec, decryptionKey.getBytes(), dec.length, 1); 
     byte[] dec2 = encrypt(enc, decryptionKey.getBytes(), enc.length, 0); 

的問題是,純文本的字節是:

 dec = {49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53} 

當我呼叫加密時:

 enc = {4, 106, -41, 38, -127, 71, 33, 77, -125, 105, -57, 82, -13, 93, 44, -125} 

,然後當我打電話解密,我得到:

 dec2 = {-103, 26, 73, -2, 64, -21, 14, -38, -51, 13, -7, 40, -83, 42, 119, -3} 

DEC和DEC2應具有相同的價值,但他們不這樣做!

我在做什麼錯?

我認爲它可能是與符號的字符轉換爲unsigned char ...我不知道這段代碼在那裏我直接鑄造jbyte *爲unsigned char * ...

謝謝!

+0

你知道enc []數組的期望值是什麼嗎?我不認爲演員會造成問題。我猜測在使用java打印時,簽名轉換可能存在問題 – jogabonito

+0

如果我使用Java的加密API,enc = {-28,-126,-104,17,105,-9,-46,72,72 ,45,1,104,-61,-66,-80,-30} 然後使用java的crypto API正確解密(即dec2 [] = dec []) – Nighthawk

回答

0

你是如何得到函數簽名的?

"Java_com_package_AESDecryptionFilterInputStream_encrypt(JNIEnv* env, 
              jobject this, 
              jbyte* data, 
              jbyte* userkey, 
              jint length, 
              jint mode)" 

在JNI字節數組中將作爲jbyteArray傳遞。 功能應該像

Java_com_package_AESDecryptionFilterInputStream_encrypt(JNIEnv* env, 
              jobject this, 
              jbyteArray data, 
              jbyteArray userkey, 
              jint length, 
              jint mode) 

您應該使用JAVAH生成簽名
您可以通過使用獲得通過(*env)->GetArrayLength(env,data) 然後,你必須複製到一個字節*傳遞的數組的長度(*env)->GetByteArrayRegion(env, data, 0, length, nativeBytePointer); 你會可能必須爲nativeBytePointer分配內存

+0

謝謝,請嘗試。我自己創造的簽名...沒有使用任何東西來生成它 – Nighthawk

+0

工作就像一個魅力!非常感謝!我做了你所說的,將簽名更改爲接收jbyteArray,然後使用GetByteArrayRegion獲取jbyte *。 謝謝你jogabonito! – Nighthawk

+0

很高興幫助:-)總是嘗試使用生成的簽名 – jogabonito