Android使用C/C++来保存密钥
本文主要介绍如何通过native方法调用取出密钥,以替代原本直接写在Java中,或写在gradle脚本中的不安全方式。
为什么要这么做
如果需要在本地存储一个密钥串,典型的方式有
1. 直接写在java source code中
2. 写在gradle脚本中,使用BuildConfig读取
3. 写在gradle.properties中,再到gradle脚本中读取,后面同第二点
4. 使用native方法,读取存放在C/C++中的字段
本质上来讲方式1,2,3**没有什么区别**。1为硬编码,2可以做到在不同的BuildType使用不同的密钥,3将配置写到脚本之外,方便管理查看。
然而,在项目编译之后,方式1,2,3都会把密钥直接替换到字节码文件中,对于反编译如此方便的Android来说,无疑是将密钥拱手让人。
因此,将密钥放在难以反编译的C/C++代码中,是一个解决的办法。
怎么做
java怎么调用C/C++方法
如果想详细的明白以下步骤,请查阅JNI相关的资料,此处仅列出大概步骤。
- 下载ndk
- 在类中声明native方法。
public class A {
public native String nativeMethod();
}
在项目根目录下新建一个名为jni的目录,并在其中新建三个文件,分别为:
- Android.mk (名字固定)
- Application.mk (名字固定)
- Project.cpp (名字随意)
Android.mk
文件的内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := project LOCAL_SRC_FILES := Project.cpp include $(BUILD_SHARED_LIBRARY)
除了
LOCAL_MODULE
和LOCAL_SRC_FILES
之外,其它都是固定的。前者是这个库的名称,后者是cpp文件的路径。Application.mk
文件的内容如下:
APP_ABI := all
意思是生成所有平台的so库。
Project.cpp
#include <jni.h> #include <stdio.h> #include <string.h> #ifdef __cplusplus extern "C"