您的位置:首页 > 编程语言 > C语言/C++

Android JNI调用c语言加密程序

2018-01-07 16:46 381 查看
在这篇博客中,我将利用NDK调用JNI来使用本地c语言实现的一个简单的加密程序,主要是为了熟悉NDK和JNI的使用方法,希望可以让后来人少踩一些坑。

系统环境

Android Studio 2.3.3

jdk1.8.0

android-ndk-r14b-windows-x86_64

配置NDK环境

下载NDK和配置环境变量在此不做赘述,不会的可以自行百度

在Android Studio中File–>ProjectStructure–>SDK Location配置“Android NDK Location”如下图:



配置gradle.properties和build.gradle文件

在项目目录下gradle.properties文件中加入

android.useDeprecatedNdk=true


修改app–>build.gradle,添加以下内容:

在defaultConfig中添加ndk项,这里moduleName是将来生成.so文件的名字,abiFilters是生成指定平台的so文件,如果不写abiFilters会生成所有平台的so文件

ndk {
moduleName "Crypto"
abiFilters "armeabi"
}


在buildTypes中添加sourceSets项,配置so文件存放位置

sourceSets {
main {
jni.srcDirs = ['libs']
}
}




添加native方法

public class Crypto {

static {
System.loadLibrary("Crypto");
}

public native String encrypt(String prim);
public native String decrypt(String code);

}


这里我们添加两个方法供以后使用,注意这里loadLibrary要和build.gradle中moduleName一致

使用javah生成对应.h头文件

在Android Studio下方Terminal进入java路径(直接将文件夹拖到命令行就进入该目录了),如果没有Terminal,从View–>Tool Windows–>Terminal打开即可。

输入命令javah -jni 包名.类名

javah -jni com.example.administrator.ndk_crypto.Crypto


生成的com_example_administrator_ndk_crypto_Crypto.h如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_administrator_ndk_crypto_Crypto */

#ifndef _Included_com_example_administrator_ndk_crypto_Crypto
#define _Included_com_example_administrator_ndk_crypto_Crypto
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_example_administrator_ndk_crypto_Crypto
* Method:    encrypt
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_encrypt
(JNIEnv *, jobject, jstring);

/*
* Class:     com_example_administrator_ndk_crypto_Crypto
* Method:    decrypt
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_decrypt
(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif




创建jni目录和.mk文件

1、在main目录下新建jni目录:

New–>Forder–>JNI Forder

2、将刚生成的.h文件复制到jni文件夹中

3、创建Crypto.c文件,引入头文件,并实现其中的方法。

#include "com_example_administrator_ndk_crypto_Crypto.h"

JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_encrypt
(JNIEnv * env, jobject obj, jstring str) {
char *prim = (*env)->GetStringUTFChars(env, str, 0);
char code[100];
int i,n,len;
char temp_char,trans_char;
int temp_num,trans_num;
len = strlen(prim);
for (int i = 0; i < len; ++i)
{
code[i] = prim[i] + 1;
}

for(i = 0;i < len;i++) {
temp_char = prim[i];                   //Consider about the corresponding number of character
if (temp_char <= 'z' && temp_char >= 'a')
temp_num = temp_char - 'a' + 1;
else if (temp_char <= 'Z' && temp_char >= 'A')
temp_num = temp_char - 'A' + 27;

trans_num = temp_num*3 % 52;

if (trans_num > 26 && trans_num <= 52)         //Transform number to character
trans_char = 'A' + trans_num - 27;
else if (trans_num > 0 && trans_num <= 26)
trans_char = 'a' + trans_num - 1;

code[i] = trans_char;
}
code[len] = '\0';
return (*env)->NewStringUTF(env, code);
}

JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_decrypt
(JNIEnv * env, jobject obj, jstring str) {
char *code = (*env)->GetStringUTFChars(env, str, 0);
char prim[100];
int i,n,len;
char temp_char,trans_char;
int temp_num,trans_num;
len = strlen(code);

for(i = 0;i < len;i++) {
temp_char = code[i];             //Consider about the corresponding digit of character
if (temp_char <= 'z' && temp_char >= 'a')
temp_num = temp_char - 'a' + 1;
else if (temp_char <= 'Z' && temp_char >= 'A')
temp_num = temp_char - 'A' + 27;

n = temp_num % 3;  //Mode 3 and compute primitive number
switch(n) {
case 0:
trans_num = temp_num/3;
break;
case 1:
trans_num = 35 + temp_num/3;
break;
case 2:
trans_num = 18 + temp_num/3;
break;
default:
break;
}
//Transform number to character
if (trans_num > 26 && trans_num <= 52)
trans_char = 'A' + trans_num - 27;
else if (trans_num > 0 && trans_num <= 26)
trans_char = 'a' + trans_num - 1;

prim[i] = trans_char;
}
prim[len] = '\0';
return (*env)->NewStringUTF(env, prim);
}


4、创建Android.mk文件

LOCAL_SRC_FILES为c文件名,LOCAL_MODULE为so文件,应该与moduleName一致

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := Crypto
LOCAL_SRC_FILES := Crypto.c

include $(BUILD_SHARED_LIBRARY)


5、创建Application.mk文件

APP_ABI := armeabi表示只支持armeabi架构的jni,如需其他架构可在后面追加

APP_CFLAGS += -Wno-error=format-security
APP_ABI := armeabi




编译so文件

在Terminal进入main目录下,执行
ndk-build




在main/libs中会生成.so文件



在main目录下新建一个jniLibs文件夹,将libs下面的文件复制到jniLibs中,编译运行即可。

运行结果



源代码

http://download.csdn.net/download/baidu_34045013/10192722

https://github.com/Caesar233/Android-NDK-Crypto
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android NDK JNI