有一年没有写博了,最近搞了一个移动项目,大致情况是:编码算法安全起见采用C/C++,封装给ANDROID和J2EE WEB服务器使用,其中涉及AES/MD5/BASE64等算法的编解码若干。
WEB服务器这边,因为是WINDOWS环境,动态库是.dll文件;ANDROID那边,因为是LINUX环境,动态库是.so文件。
A. 先整.so动态库
1. 在ANDROID项目首先在JAVA程序中定义native class
2. 在class根目录下,通过javah命令,生成 XX.h头文件。
3. 在ANDROID项目的根目录下创建jni目录,Android.mk 、Application.mk文件参考NDK的样例;
4. 写好相关的算法,整合到 XX.cpp 中
5. 编译后在 libs\armeabi\lib-XX.so
6. ANDROID中java代码的LOAD调用方法:
static
{
System.loadLibrary("util-jni");
}
B. 继续整.dll动态库
1. 在JAVA项目的class根目录下,通过javah命令,生成 XX.h头文件
2. 在VC中创建一个WINDOWS工程/解决方案,选择DLL模式
3. 加入 JDK\include\jni.h; jni_md.h(或直接加到VC根目录下面的include文件夹下)
4. 导入商数NDK的.h和.cpp文件
5. 编译出Release版本的.dll文件
6. JAVA项目中的LOAD调用方法:
static
{
System.load("F:/workspace/test/libs/XX.dll");//完整路径
}
注意事项:
a。ANDROID NDK项目的JNI写法相对比较宽松,不需要有对于的头文件,也不需要再方法中添加JNIEXPORT jTYPE JNICALL,DLL动态库项目必须要加上这段
b。JAVA、ANDROID有现成的AES等编码实现,C/C++需要找开源的,但是前者实现比较规范,后者相对比较苦逼,高地位、16位补全等问题,非常的坑爹,所以建议大家在跨平台的工具类中,建议通过C/C++来封装动态库,实现跨平台调用。
遇到的几个问题:
a。VC中AES与NDK中的AES,同样的算法编码结果不一样,会自动按16位补位,KEY改成16位,编码结果一样。
B。NDK的AES与ANDROID中的编码结果不一样,AES算法(Advanced Encryption Standard,高级加密标准)包括加密算法、工作模式、填充方式,不满16位补位等,最主要的是一般的C/C++的算法都只实现了加密算法和工作模式,对于填充方式没有开放,有个朋友讲Botan实现了,没有考证。
最后建议采用LINUX内核的服务器,呵呵