JNI包装器openssl AES_ecb_encrypt无法正常工作

时间:2011-08-03 11:13:46

标签: java-native-interface openssl aes

我正在做一个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 = "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应该具有相同的值,但它们没有!

我做错了什么?

我相信它可能是将signed char转换为unsigned char的东西...我不确定我直接将jbyte *转换为unsigned char *的那段代码...

谢谢!

1 个答案:

答案 0 :(得分: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

分配内存