从 6.0 开始,Google 要求不要使用系统的 OpenSSL,请见:https://developer.android.com...。因此,请不要再使用本文介绍的方法,请自行交叉编译 OpenSSL 或者使用别人编译好的版本。
2017年3月注

由于Java较为容易被反编译,因此把一些重要代码放在so文件中成为了一个代价不太高的选择。虽然so文件依旧可以反编译,但对so进行逆向分析的门槛则要比分析Java字节码的门槛高出不少。很多安全相关的代码都依赖OpenSSL,然而网络上在NDK中使用OpenSSL的教程并不多见,经过一天的探索,我终于可以成功在NDK中调用OpenSSL了。本文将以调用OpenSSL中的HMAC算法为例,介绍如何使用Gradle配置NDK并在NDK中使用OpenSSL。

在Gradle中配置NDK

2015年7月,Google发布了新的Gradle插件,提供了对NDK的支持,从此,编写NDK程序不再需要编写Android.mk文件,也不再需要使用ndk-build脚本,只需要在Gradle中简单的配置一下,即可方便的编译程序了。

目前,新的插件仍处在beta版本,本文选用当前时间(2016年3月2日)最新的0.6.0-beta5作介绍。要获取最新的更新,请访问这里。

从传统的Android Gradle插件迁移到新的插件并不困难,只需要修改原有目录结构中的三个文件即可。以如下目录为例:

.
├── app/
│   ├── build.gradle
│   └── src/
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle

需要修改的文件包括两个build.gradlegradle-wrapper.propertieslocal.properties文件。

分别来看对它们的修改:

每个版本的插件都只支持特定的Gradle版本,因此请务必对照上文给出的链接填写正确的版本。

  • ./local.properties

需要在文件中指定ndk.dir属性,指向NDK的路径。

  • ./gradle/wrapper/gradle-wrapper.properties

这个文件定义了Gradle的版本,这里需要使用gradle-2.10,因此需要把最后一行的版本替换掉。

  • ./build.gradle

这里定义了构建时使用的插件,需要替换为com.android.tools.build:gradle-experimental:0.6.0-beta5

  • ./app/build.gradle

这个文件变化较大,主要的变化包括:

  1. 插件名由原来的com.android.application变为com.android.model.application

  2. 所有的配置放置在model { }块中。

  3. minSdkVersiontargetSdkVersion都需要配置它们的apiLevel属性。

下面是一个完整的示例:

apply plugin: 'com.android.model.application'model {android {compileSdkVersion 23buildToolsVersion "23.0.2"defaultConfig {applicationId "com.example.openssltest"minSdkVersion.apiLevel 14targetSdkVersion.apiLevel 23versionCode 1versionName "1.0"}ndk {moduleName = "openssl-jni"platformVersion = 14ldFlags.add("-lcrypto")abiFilters.add("armeabi-v7a")}}
}dependencies {compile 'com.android.support:appcompat-v7:23.1.1'
}

这个配置中,多出了ndk部分,下面就来解释一下这部分的配置:

  • moduleName决定了编译出来的库的名称,这个选项是必须的。

  • platformVersion指定了NDK的platform版本,这里使用14是因为minSdkVersion使用14。

  • ldFlags指定了链接时的参数,由于本例中只用到了HMAC算法,因此这里添加了对crypto,如果还需要TLS的支持,这里需要改为ldFlags.addAll(["-lcrypto", "-lssl"])

  • abiFilters里指定了abi的版本armeabi-v7a

在NDK中使用OpenSSL

Android里已经内置了OpenSSL,但NDK中并没有提供相应的库。只需要把OpenSSL的.so文件放在NDK中即可:

$adb pull /system/lib/libssl.so /myndk/platforms/android-14/arch-arm/usr/lib$adb pull /system/lib/libcrypto.so /myndk/platforms/android-14/arch-arm/usr/lib

然后把OpenSSL的头文件放在 /myndk/platforms/android-14/arch-arm/usr/include 目录中即可。

编写代码请参考JNI的文档,下面给出一个调用HMAC-SHA256的实现:

#include <jni.h>
#include <openssl/hmac.h>#ifdef __cplusplus
extern "C" {
#endif
jbyteArray
Java_com_example_openssltest_MainActivity_hmacSha256(JNIEnv *env,jobject obj,jbyteArray content) {unsigned char key[] = {0x6B, 0x65, 0x79};unsigned int result_len;unsigned char result[EVP_MAX_MD_SIZE];// get data from java arrayjbyte *data = env->GetByteArrayElements(content, NULL);size_t dataLength = env->GetArrayLength(content);HMAC(EVP_sha256(),key, 3,(unsigned char *) data, dataLength,result, &result_len);// release the arrayenv->ReleaseByteArrayElements(content, data, JNI_ABORT);// the return valuejbyteArray return_val = env->NewByteArray(result_len);env->SetByteArrayRegion(return_val, 0, result_len, (jbyte *) result);return return_val;
}
#ifdef __cplusplus
}
#endif

在Java中调用也很容易,只需要引用build.gradle中指定的库即可:

public native byte[] hmacSha256(byte[] data);static {System.loadLibrary("openssl-jni");
}

DEMO项目链接

https://github.com/terro/andr...

需要注意的是,这里只是一个简单的DEMO,不要直接在项目中保存密钥之类的信息。



原文链接:https://dangfan.me/zh-Hans/po...

在Android NDK中使用OpenSSL相关推荐

  1. 【Android 逆向】Android 进程注入工具开发 ( 系统调用 | Android NDK 中的系统调用示例 )

    文章目录 一.系统调用 二.Android NDK 中的系统调用示例 一.系统调用 在 " 用户层 " , 运行的都是用户应用程序 ; 用户层 下面 是 驱动层 , 驱动层 下面是 ...

  2. android ndk使用c 11,使用c 11 std :: async在android ndk中使用不完整类型无效

    我尝试使用以下函数来检查android ndk中是否支持std :: async以及windows中的cygwin.我使用的功能如下 机器:64位赢得8与cygwin Eclipse:Juno 4.2 ...

  3. socket android用法,Android NDK中socket的用法以及注意事项分析

    与Java层中的套接字相比,本机层中的Socket可以选择更多的配置项,并获得关于当前拥塞状态的更准确的信息,那么 NDK中socket的用法以及注意事项分析,大家清楚吗?下文是爱站技术频道小编为大家 ...

  4. android源码中的ndk,如何在不需要Android操作系统源代码的情况下在Android NDK中创建新的NativeWindow?...

    我想编译一个Android OpenGL控制台应用程序,您可以直接从控制台启动Android x86或从Android x86 GUI中的Android终端应用程序运行.如何在不需要Android操作 ...

  5. android stl,Android NDK中的c++ STL

    田海立@CSDN 2020-11-25 Android NDK(Native Development Kit)提供了一套基于c/c++开发Android应用的工具.基于c/c++开发需要STL (St ...

  6. Android NDK 中堆栈日志 add2line 的分析实践

    文章目录 目的 常用的辅助工具 分析步骤 参考 目的 Android NDK 中出现的 crash 日志分析定位,使用 addr2line 对库中定位so 动态库崩溃位置,定位到某个函数的具体的代码行 ...

  7. android ndk 编译c++11,Android NDK中的c++ STL

    田海立@CSDN 2020-11-25 Android NDK(Native Development Kit)提供了一套基于c/c++开发Android应用的工具.基于c/c++开发需要STL (St ...

  8. android so导致启动慢,谈谈Android NDK中动态链接库(.so文件)的优化

    做了不少NDK相关的工作,不知道别人有没有同样的困惑,经常在编译C/C++代码的时候会出一些error或者warning,然后在网上搜,发现在Android.mk或者Application.mk文件中 ...

  9. android数据库sqlite3,android NDK中sqlite3数据库的使用

    工做须要使用数据库进行大量的插入工做,故此想经过使用c进行这部分工做,通过查资料,发现一篇文章比较实用: 方法1.使用源码sqlite3.h,sqlite3.c进行编译. 方法2.使用android编 ...

最新文章

  1. matlab球坐标曲线,matlab绘制曲线subplotsphere球面坐标绘制饼图
  2. 第 5 章 Spring Boot
  3. Python3 操作符重载方法
  4. 经典永不过时!重温设计模式
  5. java对象类型有哪些_Java中常用的对象数据类型有哪些?它们分别又占多少个字节呢?...
  6. 前端学习(2877):原生js模块化+绘制弹幕与动画video联动
  7. 单实例activemq 数据测试
  8. Restful 表述性状态传递
  9. java 只接受post请求_13SpringMvc_限定某个业务控制方法,只允许GET或POST请求方式访问...
  10. 论文阅读笔记(audio-visual相关)—Co-Separating Sounds of Visual Objects
  11. 7、机器视觉之色彩空间转换
  12. 【图像压缩】基于余弦变换及霍夫曼编码实现jpeg压缩和解压附matlab代码
  13. 河南师范大学python+学习笔记6 组合数据类型
  14. Transformer课程 业务对话机器人Rasa 3.x Reaching Out to the User
  15. tensorflow的数据读取 tf.data.DataSet、tf.data.Iterator
  16. RS485通信的学习以及思考
  17. 如需定义元素内容与边框间的空间,可使用 padding 属性,并可使用负值?
  18. DM与ML的主要区别
  19. C++11的更新内容--auto--右值引用和移动构造--1114
  20. 赵小楼《天道》《遥远的救世主》解读(89)敬畏之心下的真理

热门文章

  1. Promise 到底是什么?看这个小故事
  2. 记录一次解决httpcline请求https报handshake_failure错误
  3. 《HTML5 2D游戏编程核心技术》——第1章,第1.3节特别功能
  4. maven正确的集成命令-U-B
  5. Python脚本模拟登录网页之CSDN篇
  6. map reduce相关程序
  7. OCS2007R2升级LyncSrv2013 PART4:关联边缘
  8. 字符串表达式求值 C#实现
  9. H3C 5510 交换机DHCP设置
  10. He Fei ,First ,Good Luck