我已经使用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;
}
我的原生代码出了什么问题?任何帮助将不胜感激!