Android用C/C++来保存密钥
来源:互联网 发布:mac双系统win8.1激活 编辑:程序博客网 时间:2024/05/22 07:47
保存密钥我们可以将密钥写在如下三个地方:
1.java source code;
2.gradle中,使用BuildConfig读取;
3.写在gradle properties中,再在build gradle中读取,同第二种方法;
上述三种方法可以用且方便为什么我们要将密钥写在C/C++中呢!大家都知道写在Android代码中很容易让别人通过反编译进行读取;这样就存在很大的安全隐患;
可能有网友会问写在C/C++中别人也可以将我们的.so包拿到(将Apk解包就能拿到),然后自己声明native方法,load库,然后调用native方法,那么我们即使写在C/C++中也是白做功夫,所以今天我们来改进一下在C/C++中保存读取密钥。
改进步骤如下:
首先我们要在native代码里面,先验证一下应用的签名是否是我们的,如果是,才返回正确的密钥。
1.获取签名唯一字符串
在任意一个Activity中调用如下方法,可以得到签名的字符串。
public void getSignInfo() { try { PackageInfo packageInfo = getPackageManager().getPackageInfo( getPackageName(), PackageManager.GET_SIGNATURES); Signature[] signs = packageInfo.signatures; Signature sign = signs[0]; System.out.println(sign.toCharsString()); } catch (Exception e) { e.printStackTrace(); } }2.修改native方法的声明,传入Context对象。
public native String nativeMethod(Context context);
然后修改C++代码添加逻辑:
#include <jni.h>#include <stdio.h>#include <string.h>#ifdef __cplusplusextern "C"{#endifstatic jclass contextClass;static jclass signatureClass;static jclass packageNameClass;static jclass packageInfoClass;/** 之前生成好的签名字符串*/const char* RELEASE_SIGN = "第1步,生成好的字符串";/* 根据context对象,获取签名字符串*/const char* getSignString(JNIEnv *env,jobject contextObject) { jmethodID getPackageManagerId = (env)->GetMethodID(contextClass, "getPackageManager","()Landroid/content/pm/PackageManager;"); jmethodID getPackageNameId = (env)->GetMethodID(contextClass, "getPackageName","()Ljava/lang/String;"); jmethodID signToStringId = (env)->GetMethodID(signatureClass, "toCharsString","()Ljava/lang/String;"); jmethodID getPackageInfoId = (env)->GetMethodID(packageNameClass, "getPackageInfo","(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); jobject packageManagerObject = (env)->CallObjectMethod(contextObject, getPackageManagerId); jstring packNameString = (jstring)(env)->CallObjectMethod(contextObject, getPackageNameId); jobject packageInfoObject = (env)->CallObjectMethod(packageManagerObject, getPackageInfoId,packNameString, 64); jfieldID signaturefieldID =(env)->GetFieldID(packageInfoClass,"signatures", "[Landroid/content/pm/Signature;"); jobjectArray signatureArray = (jobjectArray)(env)->GetObjectField(packageInfoObject, signaturefieldID); jobject signatureObject = (env)->GetObjectArrayElement(signatureArray,0); return (env)->GetStringUTFChars((jstring)(env)->CallObjectMethod(signatureObject, signToStringId),0);}jstring Java_[ClassAPackage]_A_nativeMethod(JNIEnv *env,jobject thiz,jobject contextObject) { const char* signStrng = getSignString(env,contextObject); if(strcmp(signStrng,RELEASE_SIGN)==0)//签名一致 返回合法的 api key,否则返回错误 { return (env)->NewStringUTF("你的密钥"); }else { return (env)->NewStringUTF("error"); }}/** 利用OnLoad钩子,初始化需要用到的Class类.*/JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* vm,void* reserved){ JNIEnv* env = NULL; jint result=-1; if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) return result; contextClass = (jclass)env->NewGlobalRef((env)->FindClass("android/content/Context")); signatureClass = (jclass)env->NewGlobalRef((env)->FindClass("android/content/pm/Signature")); packageNameClass = (jclass)env->NewGlobalRef((env)->FindClass("android/content/pm/PackageManager")); packageInfoClass = (jclass)env->NewGlobalRef((env)->FindClass("android/content/pm/PackageInfo")); return JNI_VERSION_1_4; }#ifdef __cplusplus}#endifgetSignString方法也许看起来很复杂,如果熟悉java反射的Api的话,其实很类似,就是拿到方法的Id,调用方法。
上述这种改进的话就能防止别人破译你的密钥。
阅读全文
0 0
- Android用C/C++来保存密钥
- Android使用C/C++来保存密钥
- Android使用C/C++来保存密钥(转载)
- [C]无线网络WPAPSK密钥计算方法!!!
- ECDH密钥交换的C程序
- RC5 分组密钥算法 C语言实现
- RSA密钥证书生成(Python&C#)
- 【C#】RSA 密钥生成 加密 解密
- DiffieHillman密钥交换算法 C/C++实现
- 用c语言保存bitmap图像
- Lua C 保存状态
- 用最佳方法来管理加密密钥
- android上用C语言读取fb0实现截屏,并保存为rgb565的bmp
- android上用C语言读取fb0实现截屏,并保存为rgb565的bmp .
- android上用C语言读取fb0实现截屏,并保存为rgb565的bmp
- c/vc/c++ 将mysql二进制字段(longblob类型)读出来保存成文件
- 生成密钥,并保存
- 用emacs来编辑C(C-Mode)
- ASP.NET WebService Response.Write乱码解决
- Shell 变量--shell教程
- python--选择排序
- 《DOS命令一日通》第六章 文件的删除,改名与显示
- Timer的缺陷 用ScheduledExecutorService替代
- Android用C/C++来保存密钥
- 安卓开发框架(MVP+主流框架+基类+工具类)--- ButterKnife
- Django 数据库模型配置
- 现在学IT还来得及吗?
- js返回上一页方法
- Cas单点登录(整合shiro版本)
- 今天是场景构建的基础元年,大数据不是博眼球而是深耕行业,其与人工智能相结合是未来趋势 | 大咖周语录
- oracle的在sql语句后加for update 不是都起作用的,对于单表是可以的,但是对于多表关联(无论left join还是内连接等)都不能修改
- 谷歌发布最强AI机器人AlphaGo Zero,融360拟融资3亿美元即将赴美上市 | 大数据周周看