使用NDK方式調(diào)用jni將密碼保存到so文件中

要使用NDK首先要了解NDK到底是什么?

(英語(yǔ):native development kit,簡(jiǎn)稱NDK)是一種基于原生程序接口的軟件開發(fā)工具。通過此工具開發(fā)的程序直接以本地語(yǔ)言運(yùn)行,而非虛擬機(jī)。因此只有java等基于虛擬機(jī)運(yùn)行的語(yǔ)言的程序才會(huì)有原生開發(fā)工具包。[維基百科]

NDK是一系列工具的集合

NDK提供了一系列的工具,幫助開發(fā)者快速開發(fā)C(或C++)的動(dòng)態(tài)庫(kù),并能自動(dòng)將so和java應(yīng)用一起打包成apk。這些工具對(duì)開發(fā)者的幫助是巨大的.

NDK集成了交叉編譯器,并提供了相應(yīng)的mk文件隔離CPU、平臺(tái)、ABI等差異,開發(fā)人員只需要簡(jiǎn)單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創(chuàng)建出so。

NDK可以自動(dòng)地將so和Java應(yīng)用一起打包,極大地減輕了開發(fā)人員的打包工作。

為什么要使用?

1、代碼的保護(hù)。由于apk的java層代碼很容易被反編譯,而C/C++庫(kù)反匯難度較大。能夠阻擋一定的開發(fā)者進(jìn)行逆向。

2、可以方便地使用現(xiàn)存的開源庫(kù)。大部分現(xiàn)存的開源庫(kù)都是用C/C++代碼編寫的。

3、提高程序的執(zhí)行效率。將要求高性能的應(yīng)用邏輯使用C開發(fā),從而提高應(yīng)用程序的執(zhí)行效率。

4、便于移植。用C/C++寫得庫(kù)可以方便在其他的嵌入式平臺(tái)上再次使用。

NDK和CMake 的下載和安裝

打開android studio 找到Sdk管理器,進(jìn)行下載安裝即可。

下面開發(fā)正式開發(fā):

1、創(chuàng)建jni文件夾用來存放調(diào)用C++相關(guān)的文件,有兩個(gè)配置文件和頭文件以及源文件

配置文件:Android.mk

作用:命令行cd到src/main/jni文件夾下,使用命令ndk-build生成.so文件,這里邊定義了生成.so庫(kù)的文件名、指定編譯的c++源文件和頭文件,用于向構(gòu)建系統(tǒng)描述源文件和共享庫(kù),讓ndk去按照指定的方式編譯c++源文件和頭文件。

編譯目標(biāo)目錄聲明

LOCAL_PATH:=$(call my-dir) ? LOCAL_PATH需要編譯源文件所在的目錄,$(call my-dir)使用宏定義,my-dir是返回值對(duì)應(yīng)Android.mk所在的目錄。

重置全局變量

include $(CLEAR_VARS) ? ? ? ? ?CLEAR_VARS變量指向特殊 GNU Makefile, 可為您清除許多LOCAL_XXX變量.不包括LOCAL_PATH因?yàn)橄到y(tǒng)在單一 GNU Make 執(zhí)行環(huán)境(其中所有變量都是全局的)中解析所有構(gòu)建控制文件. 在描述每個(gè)模塊之前, 必須聲明(重新聲明)此變量

LOCAL_MODULE:=secretkey 指定模塊的名稱

LOCAL_MODULE, 指定模塊的名稱,唯一且不含空格, 之后會(huì)編譯出librecorder-jni.so, 如果模塊名已包含前綴lib, 則不會(huì)自動(dòng)添加lib前綴.

LOCAL_SRC_FILES:=secretkey.cpp secretkey.h 指定編譯c++源文件和頭文件

待編譯的源文件

LOCAL_SRC_FILES,指定源文件列表, 多個(gè)文件使用空格分割.可以使用相對(duì)文件路徑(指向 LOCAL_PATH)和絕對(duì)文件路徑

LOCAL_LDLIBS :=-llog 打印log

include $(BUILD_SHARED_LIBRARY)整合

BUILD_SHARED_LIBRARY變量指向GNU Makefile腳本, 用于收集您自最近 include 后在 LOCAL_XXX 變量中定義的所有信息.其實(shí)就是讓上一次include到這里之間的內(nèi)容生效

編譯模塊輸出名稱

LOCAL_MODULE_FILENAME, 真正的庫(kù)輸出文件名. 如果不喜歡系統(tǒng)自動(dòng)生成的文件名, 可以指定這個(gè)值

LOCAL_MODULE := foo

LOCAL_MODULE_FILENAME := libnewfoo

Application.mk

此文件枚舉并描述您的應(yīng)用需要的模塊。Android.mk有效的前提是依靠該文件的保證位于jni的目錄下.包含下面幾個(gè)方面的內(nèi)容:

用于針對(duì)特定平臺(tái)進(jìn)行編譯的 ABI。

工具鏈。

要包含的標(biāo)準(zhǔn)庫(kù)(靜態(tài)和動(dòng)態(tài) STLport 或默認(rèn)系統(tǒng))。

APP_STL := stlport_static 靜態(tài)標(biāo)準(zhǔn)庫(kù)

Android NDK 默認(rèn)使用的是最小支持的C++運(yùn)行庫(kù),如果你需要你的NDK程序中使用STL,則可以設(shè)置APP_STL := stlport_static,APP_STL有表二中的幾種取值。

NameExplanation

system(default)系統(tǒng)默認(rèn)的C++運(yùn)行庫(kù)

stlport_static以靜態(tài)鏈接方式使用的sttport版本的STL

stlport_shared以動(dòng)態(tài)鏈接方式使用的sttport版本的STL

gnustl_static以靜態(tài)鏈接方式使用的gnustl版本的STL

gnustl_shared以動(dòng)態(tài)鏈接方式使用的gnustl版本的STL

gabi++_static以靜態(tài)鏈接方式使用的gabi++

gabi++_shared以動(dòng)態(tài)鏈接方式使用的gabi++

c++_static以靜態(tài)鏈接方式使用的LLVM libc++

c++_shared以動(dòng)態(tài)鏈接方式使用的LLVM libc++

表二:NDK運(yùn)行庫(kù)

若APK中有多個(gè)SO文件用到STL,建議都使用動(dòng)態(tài)方式鏈接STL,這樣可以減小整個(gè)APK文件大小。

另外需要注意的是官方提供的NDK運(yùn)行庫(kù)除了默認(rèn)的以外都支持RTTI和異常,然而默認(rèn)是禁用的,將在下面的Android.mk中說明如何開啟。

APP_OPTIM(編譯模式)

“release”模式為默認(rèn)的,生成的是優(yōu)化后的二進(jìn)制;也可以設(shè)置為“debug”模式,“debug”模式生成的是未優(yōu)化二進(jìn)制,提供很多BUG信息,便于調(diào)試和分析

APP_PLATFORM

指定當(dāng)前程序支持android最低api水平,如APPP_PLATFORM:=16 最低支持到api16

編碼實(shí)戰(zhàn)

這里以我項(xiàng)目中使用ndk生成密匙一個(gè)例子進(jìn)行講解,實(shí)際項(xiàng)目中肯定會(huì)用到加密功能,有一些敏感的數(shù)據(jù)如用戶的密碼、賬號(hào)等,需要將這些信息保存到本地一旦數(shù)據(jù)保存到磁盤上,如果不進(jìn)行加密很有可能泄漏,造成不良的后果。

通過生成.so文件生成密匙,在一定程度上降低被盜風(fēng)險(xiǎn),畢竟這里邊設(shè)計(jì)到底層的東西比較多,安全性比硬編碼之類的高了好幾個(gè)檔次。

1、所有文件存放的位置截圖

jni存放位置

2、Android.mk配置詳細(xì)信息

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=secretkey

LOCAL_SRC_FILES:=secretkey.cpp secretkey.h

LOCAL_LDLIBS :=-llog

include $(BUILD_SHARED_LIBRARY)

3、Application.mk配置詳細(xì)信息

APP_STL := stlport_static

APP_ABI := all

#app支持最小api level

APP_PLATFORM:= android-16

APP_OPTIM? := release

4、secretkey.h

#include

#defineUTF_8"UTF-8"

#ifdef__cplusplus

extern"C"{

//com.mine.cui.zxandroidlib.jni.com.mine.cui.zxandroidlib.security.SecretKeyHelper.createSecretKey

jstring

Java_com_test_lib_security_SecretKeyHelper_createSecretKey(JNIEnv*,jobject,jobject);

}

#endif

方法格式:jstring Java+全類名 (其中.用下劃線分隔開)+java定義native方法的類名和native方法名

5、secretkey.app

#include

#include

#include"secretkey.h"

#include

#include

#defineLOG_TAG"robin_jni"http:// 自定義的LOG的標(biāo)識(shí)

#defineLOGOPEN1//日志開關(guān),1為開,其它為關(guān)

#defineLOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

#defineLOGI(...)? __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

#defineLOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)

#defineLOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)

#defineLOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)

//char* to jstring

jstringtoString(JNIEnv* env,jbyteArraybyteArray) {

jclassstring_cls = env->FindClass("java/lang/String");

jmethodIDnew_string_mid = env->GetMethodID(string_cls,"",

"([BLjava/lang/String;)V");

return reinterpret_cast(env->NewObject(string_cls, new_string_mid,

byteArray, env->NewStringUTF(UTF_8)));

}

jbyteArraytoBytes(JNIEnv* env,const char* bytes) {

jclassstring_cls = env->FindClass("java/lang/String");

jmethodIDget_bytes_mid = env->GetMethodID(string_cls,"getBytes",

"(Ljava/lang/String;)[B");

return reinterpret_cast(env->CallObjectMethod(

env->NewStringUTF(bytes), get_bytes_mid, env->NewStringUTF(UTF_8)));

}

jbyteArraytoBytes(JNIEnv* env,jstringstring) {

jclassstring_cls = env->FindClass("java/lang/String");

jmethodIDget_bytes_mid = env->GetMethodID(string_cls,"getBytes",

"(Ljava/lang/String;)[B");

return reinterpret_cast(env->CallObjectMethod(string,

get_bytes_mid, env->NewStringUTF(UTF_8)));

}

jbyteArraygetDigestedBytes(JNIEnv* env,jbyteArraycomplex_bytes) {

staticjobjectsatic_message_digest_obj = __null;

jclassmessage_digest_cls = env->FindClass("java/security/MessageDigest");

jmethodIDget_instance_mid = env->GetStaticMethodID(message_digest_cls,

"getInstance","(Ljava/lang/String;)Ljava/security/MessageDigest;");

if(satic_message_digest_obj == __null) {

jobjectlocal_message_digest_obj = env->CallStaticObjectMethod(

message_digest_cls, get_instance_mid, env->NewStringUTF("MD5"));

satic_message_digest_obj = env->NewGlobalRef(local_message_digest_obj);

env->DeleteLocalRef(local_message_digest_obj);

}

jmethodIDdigest_mid = env->GetMethodID(message_digest_cls,"digest",

"([B)[B");

env->DeleteLocalRef(message_digest_cls);

return reinterpret_cast(env->CallObjectMethod(

satic_message_digest_obj, digest_mid, complex_bytes));

}

jstringtoHex(JNIEnv* env,jbyteArraydigested_bytes) {

jclassbig_integer_cls = env->FindClass("java/math/BigInteger");

jmethodIDnew_big_integer_mid = env->GetMethodID(big_integer_cls,"",

"(I[B)V");

jobjectbig_integer_obj = env->NewObject(big_integer_cls,

new_big_integer_mid,1, digested_bytes);

env->DeleteLocalRef(digested_bytes);

jmethodIDto_String_mid = env->GetMethodID(big_integer_cls,"toString",

"(I)Ljava/lang/String;");

env->DeleteLocalRef(big_integer_cls);

return reinterpret_cast(env->CallObjectMethod(big_integer_obj,

to_String_mid,16));

}

jstringgetMD5(JNIEnv* env,jstringjInfo) {

jbyteArraydigested_bytes = getDigestedBytes(env, toBytes(env, jInfo));

returntoHex(env, digested_bytes);

}

jstringgetAppendedString(JNIEnv* env,jobjectthiz,jstrings1,jstrings2) {

const char*s1x = (env)->GetStringUTFChars(s1,NULL);

const char*s2x = (env)->GetStringUTFChars(s2,NULL);

char*sall =new char[strlen(s1x) + strlen(s2x) +1];

strcpy(sall, s1x);

strcat(sall, s2x);

jstringretval = (env)->NewStringUTF(sall);

(env)->ReleaseStringUTFChars(s1, s1x);

(env)->ReleaseStringUTFChars(s2, s2x);

free(sall);

returnretval;

}

jobjectgetInstance(JNIEnv* env,jclassobj_class) {

jmethodIDconstruction_id = env->GetMethodID(obj_class,"","()V");

jobjectobj = env->NewObject(obj_class, construction_id);

returnobj;

}

//獲取deviceid

jstringgetDeviceID(JNIEnv*env,jobjectthiz,jobjectmContext) {

jclasscls_context = (env)->FindClass("android/content/Context");

if(cls_context ==0) {

return(env)->NewStringUTF("unknown");

}

jmethodIDgetSystemService = (env)->GetMethodID(cls_context,

"getSystemService","(Ljava/lang/String;)Ljava/lang/Object;");

if(getSystemService ==0) {

return(env)->NewStringUTF("unknown");

}

jfieldIDTELEPHONY_SERVICE = (env)->GetStaticFieldID(cls_context,

"TELEPHONY_SERVICE","Ljava/lang/String;");

if(TELEPHONY_SERVICE ==0) {

return(env)->NewStringUTF("unknown");

}

jobjectstr = (env)->GetStaticObjectField(cls_context, TELEPHONY_SERVICE);

jobjecttelephonymanager = (env)->CallObjectMethod(mContext,

getSystemService, str);

if(telephonymanager ==0) {

return(env)->NewStringUTF("unknown");

}

jclasscls_tm = (env)->FindClass("android/telephony/TelephonyManager");

if(cls_tm ==0) {

return(env)->NewStringUTF("unknown");

}

jmethodIDgetDeviceId = (env)->GetMethodID(cls_tm,"getDeviceId",

"()Ljava/lang/String;");

if(getDeviceId ==0) {

return(env)->NewStringUTF("unknown");

}

jobjectdeviceid = (env)->CallObjectMethod(telephonymanager, getDeviceId);

return(jstring) deviceid;

}

//獲取SerialNumber

jstringgetSerialNumber(JNIEnv*env,jobjectthiz,jobjectmContext) {

jclasscls_tm = (env)->FindClass("android/os/SystemProperties");

if(cls_tm ==0) {

return(env)->NewStringUTF("unknown");

}

jmethodIDgetDeviceId = (env)->GetStaticMethodID(cls_tm,"get",

"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

if(getDeviceId ==0) {

return(env)->NewStringUTF("unknown");

}

jstringparam1 = (env)->NewStringUTF("ro.serialno");

jstringparam2 = (env)->NewStringUTF("unknown");

jobjectdeviceid = (env)->CallStaticObjectMethod(cls_tm, getDeviceId,

param1, param2);

return(jstring) deviceid;

}

jstringjint2jstring(JNIEnv*env,jintfirst) {

charbuf[64];// assumed large enough to cope with result

sprintf(buf,"%d", first);// error checking omitted

returnenv->NewStringUTF( buf);

}

//獲取公鑰

jstringgetPublicKey(JNIEnv* env,jobjectthiz,jobjectcontext) {

jclasscontext_cls = env->GetObjectClass(context);

jmethodIDget_package_manager_mid = env->GetMethodID(context_cls,

"getPackageManager","()Landroid/content/pm/PackageManager;");

jmethodIDget_package_name_mid = env->GetMethodID(context_cls,

"getPackageName","()Ljava/lang/String;");

env->DeleteLocalRef(context_cls);

jobjectpm_obj = env->CallObjectMethod(context, get_package_manager_mid);

jclasspm_cls = env->FindClass("android/content/pm/PackageManager");

jmethodIDget_package_info_mid = env->GetMethodID(pm_cls,"getPackageInfo",

"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");

jstringpackage_name =reinterpret_cast(env->CallObjectMethod(

context, get_package_name_mid));

jfieldIDflag_fid = env->GetStaticFieldID(pm_cls,"GET_SIGNATURES","I");

jintflag = env->GetStaticIntField(pm_cls, flag_fid);

env->DeleteLocalRef(pm_cls);

jobjectpi_obj = env->CallObjectMethod(pm_obj, get_package_info_mid,

package_name, flag);

env->DeleteLocalRef(package_name);

jclasspi_cls = env->FindClass("android/content/pm/PackageInfo");

jfieldIDsignatures_fid = env->GetFieldID(pi_cls,"signatures",

"[Landroid/content/pm/Signature;");

env->DeleteLocalRef(pi_cls);

jobjectsig_obj = env->GetObjectField(pi_obj, signatures_fid);

env->DeleteLocalRef(pi_obj);

jobjectArraysigs =reinterpret_cast(sig_obj);

jclasssignature_cls = env->FindClass("android/content/pm/Signature");

jmethodIDto_byte_array_mid = env->GetMethodID(signature_cls,"toByteArray",

"()[B");

jbyteArraysig_bytes =reinterpret_cast(env->CallObjectMethod(

env->GetObjectArrayElement(sigs,0), to_byte_array_mid));

jclasscertificate_factory_cls = env->FindClass(

"java/security/cert/CertificateFactory");

jmethodIDget_certificate_instance_mid = env->GetStaticMethodID(

certificate_factory_cls,"getInstance",

"(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;");

jobjectcertificate_factory_obj = env->CallStaticObjectMethod(

certificate_factory_cls, get_certificate_instance_mid,

env->NewStringUTF("X509"));

jmethodIDgenerate_certificate_mid = env->GetMethodID(

certificate_factory_cls,"generateCertificate",

"(Ljava/io/InputStream;)Ljava/security/cert/Certificate;");

env->DeleteLocalRef(certificate_factory_cls);

jclasscertificate_cls = env->FindClass("java/security/cert/Certificate");

jclassbyte_input_stream_cls = env->FindClass(

"java/io/ByteArrayInputStream");

jmethodIDnew_sig_bytes_is_mid = env->GetMethodID(byte_input_stream_cls,

"","([B)V");

jobjectsig_bytes_is = env->NewObject(byte_input_stream_cls,

new_sig_bytes_is_mid, sig_bytes);

env->DeleteLocalRef(sig_bytes);

env->DeleteLocalRef(byte_input_stream_cls);

jobjectcert = env->CallObjectMethod(certificate_factory_obj,

generate_certificate_mid, sig_bytes_is);

env->DeleteLocalRef(sig_bytes_is);

env->DeleteLocalRef(certificate_factory_obj);

jmethodIDget_pubic_key_mid = env->GetMethodID(certificate_cls,

"getPublicKey","()Ljava/security/PublicKey;");

env->DeleteLocalRef(certificate_cls);

jobjectpublicKey? = env->CallObjectMethod(cert, get_pubic_key_mid);

jclasspublicKey_cls = env->GetObjectClass(publicKey);

jmethodIDtoString_mid = env->GetMethodID(publicKey_cls,"toString","()Ljava/lang/String;");

jstringpublicKey_str =static_cast(env->CallObjectMethod(publicKey,toString_mid));

env->DeleteLocalRef(cert);

env->DeleteLocalRef(publicKey_cls);

env->DeleteLocalRef(publicKey);

jclassstring_cls = env->GetObjectClass(publicKey_str);

jmethodIDindexOf_mid = env->GetMethodID(string_cls,"indexOf","(Ljava/lang/String;)I");

jstringparam = env->NewStringUTF("modulus");

jintaa = env->CallIntMethod(publicKey_str,indexOf_mid,param);

jstringparam2 = env->NewStringUTF("publicExponent");

jintbb = env->CallIntMethod(publicKey_str,indexOf_mid,param2);

jmethodIDsubstring_mid = env->GetMethodID(string_cls,"substring","(II)Ljava/lang/String;");

jstringpublicKey2_str =static_cast(env->CallObjectMethod(publicKey_str,substring_mid,aa+8,bb-1));

returnpublicKey2_str;

}

//獲取簽名

jstringgetSignatures(JNIEnv* env,jobjectthizz,

jobjectthiz) {

jclassnative_clazz = env->GetObjectClass(thiz);

// 得到 getPackageManager 方法的 ID

jmethodIDmethodID_func = env->GetMethodID(native_clazz,

"getPackageManager","()Landroid/content/pm/PackageManager;");

// 獲得應(yīng)用包的管理器

jobjectpackage_manager = env->CallObjectMethod(thiz, methodID_func);

// 獲得 PackageManager 類

jclasspm_clazz = env->GetObjectClass(package_manager);

// 得到 getPackageInfo 方法的 ID

jmethodIDmethodID_pm = env->GetMethodID(pm_clazz,"getPackageInfo",

"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");

//獲取包名

jmethodIDmethodID_packagename = env->GetMethodID(native_clazz,

"getPackageName","()Ljava/lang/String;");

jstringname_str =static_cast(env->CallObjectMethod(thiz,

methodID_packagename));

// 獲得應(yīng)用包的信息

jobjectpackage_info = env->CallObjectMethod(package_manager, methodID_pm,

name_str,64);//env->NewStringUTF("com.example.contasdf")

// 獲得 PackageInfo 類

jclasspi_clazz = env->GetObjectClass(package_info);

// 獲得簽名數(shù)組屬性的 ID

jfieldIDfieldID_signatures = env->GetFieldID(pi_clazz,"signatures",

"[Landroid/content/pm/Signature;");

// 得到簽名數(shù)組,待修改

jobjectsignatur = env->GetObjectField(package_info, fieldID_signatures);

jobjectArraysignatures =reinterpret_cast(signatur);

// 得到簽名

jobjectsignature = env->GetObjectArrayElement(signatures,0);

// 獲得 Signature 類,待修改

jclasss_clazz = env->GetObjectClass(signature);

// 得到 hashCode 方法的 ID

jmethodIDmethodID_hc = env->GetMethodID(s_clazz,"hashCode","()I");

// 獲得應(yīng)用包的管理器,待修改

inthash_code = env->CallIntMethod(signature, methodID_hc);

charstr[100];

sprintf(str,"%u", hash_code);

jstringsign = env->NewStringUTF(str);

returnsign;

}

jstringgetPackageName(JNIEnv* env,jobjectthizz,jobjectthiz) {

jclassnative_clazz = env->GetObjectClass(thiz);

// 得到 getPackageManager 方法的 ID

jmethodIDmethodID_func = env->GetMethodID(native_clazz,

"getPackageManager","()Landroid/content/pm/PackageManager;");

// 獲得應(yīng)用包的管理器

jobjectpackage_manager = env->CallObjectMethod(thiz, methodID_func);

// 獲得 PackageManager 類

jclasspm_clazz = env->GetObjectClass(package_manager);

// 得到 getPackageInfo 方法的 ID

jmethodIDmethodID_pm = env->GetMethodID(pm_clazz,"getPackageInfo",

"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");

//獲取包名

jmethodIDmethodID_packagename = env->GetMethodID(native_clazz,

"getPackageName","()Ljava/lang/String;");

jstringname_str =static_cast(env->CallObjectMethod(thiz,

methodID_packagename));

returnname_str;

}

char* jstringTostring(JNIEnv* env,jstringjstr)

{

char* rtn =NULL;

jclassclsstring = env->FindClass("java/lang/String");

jstringstrencode = env->NewStringUTF("utf-8");

jmethodIDmid = env->GetMethodID(clsstring,"getBytes","(Ljava/lang/String;)[B");

jbyteArraybarr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);

jsizealen = env->GetArrayLength(barr);

jbyte* ba = env->GetByteArrayElements(barr,JNI_FALSE);

if(alen >0)

{

rtn = (char*)malloc((size_t) (alen +1));

memcpy(rtn, ba, (size_t) alen);

rtn[alen] =0;

}

env->ReleaseByteArrayElements(barr, ba,0);

returnrtn;

}

jstring Java_com_test_lib_security_SecretKeyHelper_createSecretKey(JNIEnv* env,jobjectthizz,

jobjectthiz) {

jstringimei = getAppendedString(env, thizz, getDeviceID(env, thizz, thiz),getSerialNumber(env, thizz, thiz));

if(LOGOPEN==1){

LOGD("imei = %s",jstringTostring(env,imei));

}

jstringsign = getPublicKey(env, thizz, thiz);

if(LOGOPEN==1){

LOGD("sign = %s",jstringTostring(env,sign));

}

jstringimei_sign = getAppendedString(env, thizz, imei, sign);

if(LOGOPEN==1){

LOGD("imei_sign = %s",jstringTostring(env,imei_sign));

}

jstringpackage = getPackageName(env, thizz, thiz);

if(LOGOPEN==1){

LOGD("package = %s",jstringTostring(env,package));

}

jstringimei_sign_package = getAppendedString(env, thizz, imei_sign,package);

if(LOGOPEN==1){

LOGD("imei_sign_package = %s",jstringTostring(env,imei_sign_package));

}

//請(qǐng)?jiān)偌尤胱约旱囊莆换蛱鎿Q 或其他加密算法,例如我又append了一次imei

imei_sign_package = getAppendedString(env, thizz, imei_sign_package, imei);

if(LOGOPEN==1){

LOGD("imei_sign_package2 = %s",jstringTostring(env,imei_sign_package));

}

imei_sign_package = getAppendedString(env, thizz, imei_sign_package, sign);

if(LOGOPEN==1){

LOGD("imei_sign_package3 = %s",jstringTostring(env,imei_sign_package));

}

jstringsecretKey = getMD5(env, imei_sign_package);

if(LOGOPEN==1){

LOGD("secretKey = %s",jstringTostring(env,secretKey));

}

returnsecretKey;

}

6、、

public class SecretKeyHelper {

static{

System.loadLibrary("secretkey");

}

private staticStringmKey;

public staticString getSecretKey(Context context) {

if(mKey==null) {

mKey=createSecretKey(context);

}

returnmKey;

}

public static nativeString createSecretKey(Context context);

}

8、

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,530評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,759評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,204評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,415評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,955評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,675評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容