用到了C语言AES加解密,代码是从Linux内核提取的;
原代码的key是:
const char *key_string="1234567890123";
实际使用要对key做处理,通过java端传进来的jstring:
const char *key_str=(*env)->GetStringUTFChars(env, jkey, 0);
用key_string加解密是没问题的,用key_str加密ok,解密就会出现乱码错误;所以怀疑是转换除了问题;
C语言的字符串比较复杂,有些不理解。
对比了二个字符串:
1. strcmp(key_string, key_str) 返回 0;
2. strlen(key_string)=13, sizeof(key_string)=4
3. strlen(key_str)=13, sizeof(key_str)=4
求SF大神指点!
附上源码:
jstring
Java_com_itapp_mylibrary_MyLibrary_encrity(JNIEnv* env, jobject this,jstring jstr,jstring jkey)
{
const char *key_string="1234567890123";
//1. 将unicode编码的java字符串转换成C风格字符串
const char *key_str=(*env)->GetStringUTFChars(env, jkey, 0);
LOGI("setAES----key_string:%s,key_str:%s,key_string:%d",key_string,key_str,strcmp(key_string, key_str));
LOGI("strlen(key_string)=%d, sizeof(key_string)=%d", strlen(key_string), sizeof(key_string));
LOGI("strlen(key_str)=%d, sizeof(key_str)=%d", strlen(key_str), sizeof(key_str));
//2. 释放内存
(*env)->ReleaseStringUTFChars(env, jkey, key_str);
const char *str_input = (*env)->GetStringUTFChars(env, jstr, NULL); //待加密内容,转换格式
long strLen = ((strlen(str_input) / 16) * 16) + 16; //计算该给字符串的长度 (字符长度/16)*16+16 以确保长度为16的倍数
//开始AES加密
char * aesEnc = malloc(strLen);
memset(aesEnc, 0, strLen);
AES_set_encrypt_key(key_string, 256, &key); //设置AES加密密钥
for (i = 0; i < strlen(str_input); i += 16)AES_encrypt(str_input + i, aesEnc + i, &key); //循环进行AES加密
//开始Base64一次加密
char *basEnc = base64_encode(aesEnc, strlen(aesEnc)); //Base64加密
//拼接长度到 加密字符 在加密内容后拼接 原字符串长度
char len[strLen+2];
sprintf(len,"%d__",strLen);
char *len_str = str_contact(len,basEnc);
//进行Base64二次加密
char *result = base64_encode(len_str, strlen(len_str)); //Base64加密
LOGI("setAES----result:%s", result);
//转换为 jstring 并返回
return (*env)->NewStringUTF(env, result);
}
/分割线**/
jstring
Java_com_itapp_mylibrary_MyLibrary_decrity(JNIEnv* env, jobject this,jstring jstr,jstring jkey)
{
char *key_string="1234567890123";
//1. 将unicode编码的java字符串转换成C风格字符串
const char *key_str=(*env)->GetStringUTFChars(env, jkey, 0);
//2. 释放内存
(*env)->ReleaseStringUTFChars(env, jkey, key_str);
const char *str_output = (*env)->GetStringUTFChars(env, jstr, NULL); //获取待揭秘内容,转换格式
//进行Base64一次解密
char *len_str = base64_decode(str_output, strlen(str_output)); //Base64解密,解密basEnc,得basDec
//分割字符串
char str[strlen(len_str)]; //原始字符串
char cstrlen[16]; //源字符串长度
sscanf(len_str, "%[0-9]__%[^.]", cstrlen,str); //获取字符串内容
long strLen = atoi(cstrlen); //截取字符串原长度
//进行Base64二次解密
char *basDec = base64_decode(str, strlen(str)); //Base64解密,解密basEnc,得basDec
//进行AES解密
char * aesDec = malloc(strLen);
memset(aesDec, 0, strLen);
AES_set_decrypt_key(key_string,256,&key); //设置AES解密密钥
for(i=0;i<strLen;i+=16)AES_decrypt(basDec+i,aesDec+i,&key); //进行AES解密,解密basDec,得aesDec
LOGI("getAES----aesDec:%s", aesDec);
//转换为 jstring 并返回
return (*env)->NewStringUTF(env, aesDec);
}
strcmp(key_string, key_str) 返回 0;
strlen(key_string)=13, sizeof(key_string)=4
strlen(key_str)=13, sizeof(key_str)=4
这三条, 说明你的key_str与key_string是完全相同的.
怀疑是这里的问题
AES_set_encrypt_key(key_string, 256, &key);
因为你的密钥只有13字节的长度, 即使13*8也才104位, 所以你传的256估计是越界访问到的不确定的数据
就是因为这个不确定的数据, 导致加密和解密时密钥不同了, 所以解密后是乱码了.