调用本机功能加密数百次时,应用程序崩溃

时间:2014-02-06 07:50:56

标签: android c android-ndk openssl aes

我已经使用OpenSSL库完成了用C编写的AES加密包装器。我在Android项目中使用了这个包装器。当我调用加密函数数百次来加密很多小文件(图像)时,它引起了崩溃错误:

02-06 14:39:44.110: A/libc(5114): @@@ ABORTING: INVALID HEAP ADDRESS IN dlfree
02-06 14:39:44.110: A/libc(5114): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)

这是内存泄漏错误,但我无法弄清楚自己。我猜我的本机代码出了问题。下面是我使用OpenSSL库用C编写的加密函数。 (由NDK编制)

函数init加密密钥

int aes_init_encrypt(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx)
{
    int i, nrounds = 4;
    unsigned char key[16], iv[16];

    /*
     * Gen key & IV for AES 128 CBC mode. A SHA1 digest is used to hash the supplied key material.
     * nrounds is the number of times the we hash the material. More rounds are more secure but
     * slower.
     */
    i = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
    if (i != 16)
    {
        //__android_log_write(ANDROID_LOG_ERROR, "TamNV-Encryption", "Key size is %d bits - should be 128 bits\n");
        return -1;
    }

    EVP_CIPHER_CTX_init(e_ctx);
    EVP_EncryptInit_ex(e_ctx, EVP_aes_128_cbc(), NULL, key, iv);

    return 0;
}

功能加密

jint Java_com_openssl_aes_WrapperAES_encryptAES(JNIEnv *env, jobject obj, jstring password, jstring source, jstring destination)
{
    FILE* source_file;
    FILE* destination_file;

    const char *source_path = (*env)->GetStringUTFChars(env, source, NULL);
    const char *destination_path = (*env)->GetStringUTFChars(env, destination, NULL);

    source_file = fopen(source_path, "rb");
    destination_file = fopen(destination_path, "wb");

    if (source_file == NULL || destination_file == NULL) {
        return -1;
    }

    // Prepare to encrypt
    // 1. Get password
    const char *pass = (*env)->GetStringUTFChars(env, password, NULL);
    unsigned char *key_data = malloc(strlen(pass));
    if (key_data)
        strcpy(key_data, pass);
    else
        return -1;

    // 2. Init EVP_CIPHER
    EVP_CIPHER_CTX e_ctx;
    if (aes_init_encrypt(key_data, strlen(key_data), key_data, &e_ctx) == -1)
    return -1;

    /* Buffers */
    unsigned char inbuf[BUFFER_SIZE];
    int inlen;
    /* Allow enough space in output buffer for additional cipher block */
    unsigned char outbuf[BUFFER_SIZE + AES_BLOCK_SIZE];
    int outlen;
    int writelen;

    while ((inlen = fread(inbuf, 1, BUFFER_SIZE, source_file)) > 0) {
        //      fwrite(inbuf, 1, inlen, destination_file);
        if (!EVP_CipherUpdate(&e_ctx, outbuf, &outlen, inbuf, inlen)) {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&e_ctx);
            return -1;
        }

        writelen = fwrite(outbuf, sizeof(*outbuf), outlen, destination_file);
        if (writelen != outlen) {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&e_ctx);
            return -1;
        }
    }

    /* Handle remaining cipher block + padding */
    if (!EVP_CipherFinal_ex(&e_ctx, outbuf, &outlen)) {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&e_ctx);
        return -1;
    }
    /* Write remainign cipher block + padding*/
    fwrite(outbuf, sizeof(*inbuf), outlen, destination_file);
    EVP_CIPHER_CTX_cleanup(&e_ctx);

    fclose(source_file);
    fclose(destination_file);

    free(key_data);

//  __android_log_print(ANDROID_LOG_DEBUG, "TamNV","Encrypt successfully --- %s", source_path);
    return 0;
}

我的原生代码出了什么问题?任何帮助将不胜感激!

0 个答案:

没有答案