前言
我會在小專欄和簡書一起分享。
最近在忙其他事情,今天想起JNI做加解密不錯,于是我調(diào)查了一下AES使用JNI實現(xiàn),試驗過程發(fā)現(xiàn)用C或者C++出了很多問題,于是發(fā)現(xiàn)有人使用一種巧妙的方式,用Java做加解密,只是把加解密的Key放在SO庫中,這里我要講的就是這種方式。
正文
新建java類
public class AESjni {
public static native String myEncrypt(String str);
public static native String myDecrypt(String str);
}
還是使用我們的Tools工具生成.h文件

接著編寫c文件
#include "com_crayfish_ndkproject_AESjni.h"
#include <stdlib.h>
const char *DES_KEY = "12345678912345678912345678912345";
/*
* Class: com_jzp_myapplication_JniUtils
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_crayfish_ndkproject_AESjni_myEncrypt
(JNIEnv *env, jclass jclass1, jstring jstr)
{
if (jstr == NULL) {
return NULL;
}
jstring key;
jstring result;
jclass AESencrypt;
jmethodID mid;
AESencrypt = (*env)->FindClass(env, "com/crayfish/ndkproject/AESjni");
if (NULL == AESencrypt) {
return NULL;
}
mid = (*env)->GetStaticMethodID(env, AESencrypt, "encrypt",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
if (NULL == mid) {
(*env)->DeleteLocalRef(env, AESencrypt);
return NULL;
}
key = (*env)->NewStringUTF(env, DES_KEY);
result = (*env)->CallStaticObjectMethod(env, AESencrypt, mid, key, jstr);
(*env)->DeleteLocalRef(env, AESencrypt);
(*env)->DeleteLocalRef(env, key);
return result;
}
JNIEXPORT jstring JNICALL Java_com_crayfish_ndkproject_AESjni_myDecrypt
(JNIEnv *env, jclass jclass1, jstring jstr)
{
if (jstr == NULL) {
return NULL;
}
jstring key;
jstring result;
jclass AESencrypt;
jmethodID mid;
AESencrypt = (*env)->FindClass(env, "com/crayfish/ndkproject/AESjni");
if (NULL == AESencrypt) {
return NULL;
}
mid = (*env)->GetStaticMethodID(env, AESencrypt, "decrypt",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
if (NULL == mid) {
(*env)->DeleteLocalRef(env, AESencrypt);
return NULL;
}
key = (*env)->NewStringUTF(env, DES_KEY);
result = (*env)->CallStaticObjectMethod(env, AESencrypt, mid, key, jstr);
(*env)->DeleteLocalRef(env, AESencrypt);
(*env)->DeleteLocalRef(env, key);
return result;
}
看到c代碼中有讀取java類中encrypt和decrypt兩個方法了吧,我們把它們補上,這里就是真正的加解密邏輯。
public static String encrypt(String key,String palinText) throws Exception{
//加密
return "";
}
public static String decrypt(String key,String palinText) throws Exception{
//解密
return "";
}
記得配置Android.mk和build.gradle
include $(CLEAR_VARS)
LOCAL_MODULE := AESjni
LOCAL_SRC_FILES := aesjni.c
include $(BUILD_SHARED_LIBRARY)
ndk{
moduleName "AESjni" //生成的so名字
//abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定三種abi體系結(jié)構(gòu)下的so庫。目前可有可無。
}
結(jié)尾
今天的內(nèi)容很簡單,到這就結(jié)束了。