Оболочка JNI для openssl AES_ecb_encrypt не работает - PullRequest
0 голосов
/ 03 августа 2011

Я делаю JNI-оболочку для вызова функции AES_ecb_encrypt из openssl.

Оболочка выглядит так:

#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 = "0123456789012345".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 должны иметь одно и то же значение, но они не имеют!

Что я делаю не так?

Я полагаю, что это может быть что-то с преобразованием подписанного char в unsigned char ... Я не уверен в том куске кода, где я приводил jbyte * непосредственно к unsigned char * ...

Спасибо!

1 Ответ

0 голосов
/ 04 августа 2011

Как вы получили сигнатуру функции?

"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

...