1.
linux安装openssl库
参见《精通PKI网络安全认证技术与编程实现》2.3.2节 Linux下搭建OpenSSL开发环境
Linux下面解压tar.bz2文件:tar jxvf android-ndk-r5c-linux-x86.tar.bz2
2. 配置NDK的环境变量
在~/.bashrc文件末尾添加:
NDK=~/android-ndk-r4b
export NDK
执行source ~/.bashrc
如果有终端已经运行,需要在重启终端才能使用NDK变量
3. JNI介绍
JNI主要功能就是能够调用到C库,在这里我们需要用C或C++调用openssl库实现加密签名等功能,然后编译成arm体系的so库,用java调用提供的接口。
详细介绍参见此书:《TheJava
Native Interface: Programmer’s Guide and Specification》
4. 下载android版本的openssl,编译
现在网上我看见过3种版本的android-openssl,fries版本,eighthave版本以及guardianproject版本,前面两个版本有测试过但是没有尝试成功,guardianproject版本编译成静态库再给android的JNI动态库程序调用的话会找不到方法,不清楚是什么原因,但是直接将JNI程序与openssl工程一起编译就可以实现。
下面这个blog有说编译openssl静态库给android用,但是不知道他用的是什么版本的Openssl,我按照他的方法尝试没有成功。
http://blog.csdn.net/someonea/article/details/6312213
guardianproject版本原版下载地址:
https://github.com/guardianproject/openssl-android
我修改过的版本:
http://download.csdn.net/source/3408214
在我修改过的版本中可以直接在myAPP文件夹下编写JNI程序,与Openssl一起打包编译成动态库就行了。
编译时可能出现一些undefined reference,大部分可能是没有添加链接库,有些情况也可能是NDK版本问题,最好用最新版本的NDK(我用的r5c),注意有没添加以下两个静态库
LOCAL_LDLIBS := -lz –ldl
5. 将编译完的so库放置android工程目录的libs/armeabi目录下
6. JAVA调用动态库
下面是本人测试时写的一个两数相加的:
Java code
native方法:
public native int add(int a,int b);
load库:
static {
System.loadLibrary("add");//编译完的都是带Lib开头的,这里Load不要加
}
7. 在c程序中调用android的log,记录运行信息
表示完全不会用gdb调试这玩意,只好用log一步步记录了…..
view plainprint?
C/C++ code
#include<android/log.h>
#define LOG_TAG"show infomation" //这个是log标签,内容自己设置
#define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a)
//除了这个方法还有__android_log_print方法,跟printf很像,具体可以看android/log.h里面
Makefile中LOCAL_LDLIBS:= -L$(SYSROOT)/usr/lib –llog
8. bouncyCastle结合openssl进行密钥管理
参见这个博客的介绍
http://blog.csdn.net/zhenyongyuan123/article/details/5558562
本人已经尝试成功用bouncyCastle在android上生成密钥库和密钥对,
这里需要注意的是Android上本身有bouncyCastle包,如果直接导入包会在运行时报找不到类等错误
我们需要下载bouncyCastle源码,修改包名比如org.bouncyCastle2等,编译打包成jar
Build Path->Add External Archives添加包,不然运行时也会报找不到类错误,这个可能是因为没有将jar包打入apk中。
9. openssl与cryptoAPI对称加密的兼容问题
cryptoAPI本身不支持传明文密钥进去,需要通过genKey或者DeriveKey得到Key句柄,
而这里面不仅仅只是对传进去的密钥进行hash算法,具体可参见MSDN
http://msdn.microsoft.com/en-us/library/aa379916%28v=VS.85%29.aspx
Remarks里面的
If the hash is not a member of the SHA-2
family and therequired key is for either 3DES or AES,
the key is derived as follows:下面六个步骤。
我们可以通过公钥加密,私钥解密查看到cryptoAPI进行对称加密的会话密钥,这里已经有完整的代码:
http://www.codeproject.com/KB/security/plaintextsessionkey.aspx
在使用openssl的evp封装好的对称加密时貌似有点问题,可能是我使用错了,使用下面这种方式可以与cryptoAPI的加密匹配上
http://blog.csdn.net/lyjinger/article/details/1722570
10. 有些时候可能只需要NDK编译出静态库,但是如果不加上动态库会什么都不编译
这里只编译静态库需要在JNI下面建立一个Application.mk,需要在该文件中加上一句:
APP_MODULES := libexample(模块名称)
11. 另外,Android上面有一个证书安装的功能,没有真机,不了解什么用途
在android模拟器的setting里面可以找到Location&security栏,里面可以install
from SD card安装加密的证书,p12格式的,带私钥的。安装后可以在Data/misc/keystore找到对应的证书,密钥等文件,代码操作没有权限。
System/etc/security下面存在cacerts.bks,BouncyCastle密钥库,读取时提示完整性检查失败,这个文件也应该是没有权限访问的 |