openssl移植Android使用及其相关经验分享

来源:互联网 发布:c语言鸡兔同笼代码 编辑:程序博客网 时间:2024/05/22 06:08

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

注明下:如果是下的本人修改的openssl源码,使用android-8的版本,在本人上传的openssl源码中default.properties可以更改版本

5.      将编译完的so库放置android工程目录的libs/armeabi目录下


6.      JAVA调用动态库

下面是本人测试时写的一个两数相加的:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. native方法:  
  2.   
  3. public native int add(int a,int b);  
  4.   
  5.  load库:  
  6.   
  7.      static {  
  8.   
  9.         System.loadLibrary("add");//编译完的都是带Lib开头的,这里Load不要加  
  10.   
  11. }  


7.      在c程序中调用android的log,记录运行信息

表示完全不会用gdb调试这玩意,只好用log一步步记录了…..

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include<android/log.h>  
  2.   
  3. #define LOG_TAG"show infomation"   //这个是log标签,内容自己设置  
  4.   
  5. #define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a)  //除了这个方法还有__android_log_print方法,跟printf很像,具体可以看android/log.h里面  
  6.   
  7. 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密钥库,读取时提示完整性检查失败,这个文件也应该是没有权限访问的

---------------------------------------------------------------------------------------------------------------

cacerts.bks是有权限读取的,默认密码时changeit,如果密码错误则出现完整性检查失败

如果需要修改cacerts.bks可以尝试使用remount或者chmod修改读写权限,再访问

certInstaller安装的证书还未找到方法操作,看过CertInstaller的源码,模拟做了一遍依然无效

有朋友说这个只提供给wifi或者vpn使用,隐隐中感觉还是有办法获取,只是没用对

(有兴趣的朋友可以再试试android.security.KeyStore中的方法,模拟empty返回的false,说明可以获取正确数值

但是有些方法需要参数key,试了很多依然没有成功)

0 0
原创粉丝点击