`

在ndk中获取apk签名文件的MD5值

 
阅读更多

最近在弄ndk,需要做一个用纯C校验签名的功能,也看了一些帖子,主要是参考下面两个:

主要思路是参考这个帖子,java代码和c代码都是,但是这个帖子里有几个小错误

http://blog.csdn.net/lgl1170860350/article/details/46348965

有的地方看了下这个帖:

http://blog.csdn.net/leifengpeng/article/details/52681196

因为同时用的是unity3D,没法传context参数给我,还顺便研究了下怎么获取context,参考贴:

http://blog.csdn.net/xiaogazhang/article/details/46891139

 

我的代码:

	bool soulgameCheckMD5InPureC(jobject context,JNIEnv *env){
		SGLOGD("soulgameCheckMD5InPureC() begin!");

		//
		jclass tem_class;
		jmethodID tem_method;
		jclass class_context = env->GetObjectClass(context);

		//PackageInfo localPackageInfo = context.getPackageManager()
		tem_method = env->GetMethodID(class_context, "getPackageManager", "()Landroid/content/pm/PackageManager;");
		jobject obj_package_manager = env->CallObjectMethod(context, tem_method);
		if(obj_package_manager == NULL){
			SGLOGD("soulgameCheckMD5InPureC() getPackageManager failed!");
			return false;
		}

		// getPackageName
		tem_method = env->GetMethodID(class_context, "getPackageName", "()Ljava/lang/String;");
		jobject obj_package_name = env->CallObjectMethod(context, tem_method);
		env->DeleteLocalRef(class_context);
		env->DeleteLocalRef(context);
		if(obj_package_name == NULL){
			SGLOGD("soulgameCheckMD5InPureC() getPackageName failed!");
			return false;
		}

		// getPackageInfo
		tem_class = env->GetObjectClass(obj_package_manager);
		tem_method = env->GetMethodID(tem_class, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
		jobject obj_package_info = env->CallObjectMethod(obj_package_manager, tem_method, obj_package_name, 64);
		env->DeleteLocalRef(obj_package_name);
		env->DeleteLocalRef(obj_package_manager);
		if(obj_package_info == NULL){
			SGLOGD("soulgameCheckMD5InPureC() getPackageInfo failed!");
			return false;
		}

		// Signature[] arrayOfSignature = localPackageInfo.signatures;
		tem_class = env->GetObjectClass(obj_package_info);
		jfieldID fieldID_signatures = env->GetFieldID(tem_class, "signatures", "[Landroid/content/pm/Signature;");
		// Signature localSignature = arrayOfSignature[0];
		jobject signatur = env->GetObjectField(obj_package_info, fieldID_signatures);
		jobjectArray signatures = (jobjectArray)(signatur);
		jobject signature = env->GetObjectArrayElement(signatures, 0);
		env->DeleteLocalRef(signatures);
		env->DeleteLocalRef(obj_package_info);
		if(signatur == NULL){
			SGLOGD("soulgameCheckMD5InPureC() signatures failed!");
			return false;
		}

		// localSignature.toByteArray()
		tem_class = env->GetObjectClass(signature);
		tem_method = env->GetMethodID(tem_class, "toByteArray", "()[B");
		jobject obj_sign_byte_array = env->CallObjectMethod(signature, tem_method);// 这个就是拿到的签名byte数组
		env->DeleteLocalRef(signature);
		env->DeleteLocalRef(tem_class);
		if(obj_sign_byte_array == NULL){
			SGLOGD("soulgameCheckMD5InPureC() toByteArray failed!");
			return false;
		}

		// MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
		jclass class_MessageDigest = env->FindClass( "java/security/MessageDigest");
		tem_method = env->GetStaticMethodID( class_MessageDigest, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;");
		jobject obj_md5 = env->CallStaticObjectMethod( class_MessageDigest, tem_method, env->NewStringUTF("md5"));
		if(obj_md5 == NULL){
			SGLOGD("soulgameCheckMD5InPureC() getInstance failed!");
			return false;
		}

		// localMessageDigest.update(localSignature.toByteArray());
		tem_method = env->GetMethodID(class_MessageDigest, "update", "([B)V");// 这个函数的返回值是void,写V
		env->CallVoidMethod(obj_md5, tem_method, obj_sign_byte_array);
		env->DeleteLocalRef(obj_sign_byte_array);

		// localMessageDigest.digest()
		tem_method = env->GetMethodID(class_MessageDigest, "digest", "()[B");
		// 这个是md5以后的byte数组,现在只要将它转换成16进制字符串,就可以和之前的比较了
		jbyteArray obj_array_sign = (jbyteArray)env->CallObjectMethod(obj_md5, tem_method);// jni中有强转类型的概念吗
		env->DeleteLocalRef(obj_md5);
		env->DeleteLocalRef(class_MessageDigest);
		if(obj_array_sign == NULL){
			SGLOGD("soulgameCheckMD5InPureC() digest failed!");
			return false;
		}

		// 尝试用c写一下:http://blog.csdn.net/pingd/article/details/41945417
		jsize int_array_length = env->GetArrayLength(obj_array_sign);
		jbyte* byte_array_elements = env->GetByteArrayElements(obj_array_sign, NULL);
		char* char_result = (char*) malloc(int_array_length*2+1);// 开始没有+1,在有的情况下会越界产生问题,还是在后面补上\0比较好

		// 将byte数组转换成16进制字符串,发现这里不用强转,jbyte和unsigned char应该字节数是一样的
		ByteToHexStr((unsigned char*)byte_array_elements, char_result, int_array_length);
		*(char_result+int_array_length*2) = '\0';// 在末尾补\0
//		jstring string_result = env->NewStringUTF(char_result);
//		env->DeleteLocalRef(string_result);

		// release
		env->ReleaseByteArrayElements( obj_array_sign, byte_array_elements, JNI_ABORT);
		env->DeleteLocalRef(obj_array_sign);

		//校验
		const char* pWhiteObject;
		bool bIsMD5Right;
		int nIndex = 0;
		int nLen = sizeof(pMD5WhiteList)/4;
		for(nIndex = 0;nIndex<nLen;nIndex++){
			pWhiteObject = pMD5WhiteList[nIndex];
			if( strcmp(char_result,pWhiteObject) == 0 ){
				break;
			}
		}
		if(nIndex<nLen){
			bIsMD5Right = true;
		}else{
			bIsMD5Right = false;
		}

		// 释放指针使用free
		free(char_result);

		SGLOGD("soulgameCheckMD5InPureC() finish!");
		if(bIsMD5Right){
			return true;
		}else{
			return false;
		}
	}

 

 

分享到:
评论

相关推荐

    ndk开发实战javap签名篇

    标题“ndk开发实战javap签名篇”指向了一个针对使用NDK进行Android应用开发过程中的具体技术实践——使用javap命令来获取Java类的签名信息,并生成相应的C/C++头文件,这对于在C/C++代码中调用Java层的方法是必需的...

    android平台基于ndk c语言和java语言的md5加密

    本主题主要探讨如何在Android中结合Java和NDK(Native Development Kit)使用C语言实现MD5加密。 MD5是一种广泛使用的哈希函数,它将任意长度的数据转化为固定长度的128位(16字节)摘要,通常以32位十六进制数的...

    Android-NDK-MD5-安卓jni 进行md5加密

    在Android开发中,有时我们需要对数据进行加密处理以保护信息安全,MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,常用于文件校验和数据加密。本主题聚焦于如何在Android环境中,利用JNI(Java ...

    Android中使用JNI获得APK签名的哈希值例子

    上次发的代码: http://download.csdn.net/detail/iloveyoueveryday/6909583 好多人说调不通,于是做了个小例子,改了一些东西(其实还是一样的),给大家看看,要是还有问题,就说明是你的NDK环境没有设置好了

    JniCheckSign:一个使用ndk检查签名md5值,防止其他人使用.so文件的演示

    首先,项目会获取当前应用的签名MD5值,这个值可以在应用的APK打包过程中获取。然后,它将此MD5值与.so文件中预存的签名值进行比较。如果两者匹配,说明.so文件正在正确的应用环境中运行;如果不匹配,则表明可能有...

    Android ndk下获取系统使用时间

    当我们需要在Android NDK环境中获取系统的使用时间时,通常涉及到的是获取系统运行的时间戳或者CPU的使用情况。本文将详细介绍如何在Android NDK环境下实现这一功能。 首先,我们需要理解“系统使用时间”可能有两...

    Android so文件签名验证源代码

    本文将基于给定的"Android so文件签名验证源代码"主题,详细阐述Android SO文件的签名过程、NDK(Native Development Kit)的使用以及签名验证的重要性。 首先,了解Android应用签名机制是理解SO文件签名验证的基础...

    ndk的md5加密

    在"ndk的md5加密"这个主题中,我们主要讨论如何在NDK环境下实现MD5加密。在Android应用开发中,有时我们需要在原生层处理数据,比如进行复杂的运算或加密,这时NDK就派上用场了。MD5加密是将任意长度的数据转换为...

    android jni 获取md5码

    在这个特定的例子中,我们将探讨如何使用JNI来计算字符串的MD5值。MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,可以将任意长度的输入转换为固定长度的输出,通常用于数据校验和完整性检查。 首先...

    Linux下用NDK和SDK工具将库文件打包进apk应用.pdf

    Linux下用NDK和SDK工具将库文件打包进apk应用.pdfLinux下用NDK和SDK工具将库文件打包进apk应用.pdf

    md5.zip_C md5_md5

    标题中的"md5.zip_C md5_md5"表明这是一个关于C语言实现MD5算法的压缩文件,其中可能包含了源代码和相关示例。MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,可以将任意长度的数据转化为固定长度的...

    Android NDK 获取系统版本号

    博客名称 : 【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 ) 博客地址 : https://hanshuliang.blog.csdn.net/article/details/102933704

    Android NDK实现apk文件的增量更新

    在增量更新的过程中,服务器会生成一个例如12M左右的差分包,用户只需要将这个差分包下载到手机本地,与旧版应用的apk文件进行合并,即可得到新版应用的apk文件,这个过程实际上就是在打补丁,比起传统的应用更新,...

    android JNI运行NDK编译成的可执行文件

    4. **加载和运行可执行文件**:在Android应用中,我们需要获取可执行文件的路径,这可能需要将可执行文件作为资产或资源打包到APK中。然后,通过JNI函数调用`system()`或`exec()`函数来运行可执行文件。注意,这种...

    08_19_NDK_文件拆分_文件合并_大型应用跨平台解决方案

    08_19_NDK_文件拆分_文件合并_大型应用跨平台解决方案08_19_NDK_文件拆分_文件合并_大型应用跨平台解决方案08_19_NDK_文件拆分_文件合并_大型应用跨平台解决方案08_19_NDK_文件拆分_文件合并_大型应用跨平台解决方案...

    NDK的android.mk文件的详解

    在文件的开头,`$(call my-dir)`函数被用来获取当前Makefile的目录,确保`LOCAL_PATH`指向正确的源代码位置。这通常是必要的,因为`android.mk`可能被包含在不同的目录层级中。 `include $(CLEAR_VARS)`语句清除了...

    通过NDK获得UUID

    在Android开发中,有时我们需要获取设备的唯一标识符来实现特定功能,如用户跟踪或设备绑定。...通过查看和分析这些代码,你可以更好地理解如何在Android中通过NDK和Java层获取UUID或设备唯一标识。

    android ndk r5 配置

    然而,在实际应用过程中,需要注意 NDK 的局限性,特别是在与 Java 代码交互以及处理 Android 系统事件方面。此外,对于不同版本的 ABI 支持情况也需要格外留意,以确保应用程序在不同设备上的兼容性和稳定性。

    mac--ndk配置

    在Android开发过程中,NDK(Native Development Kit)是一个不可或缺的工具,它允许开发者使用C和C++编写原生代码,从而提升应用性能、利用硬件特性并实现底层优化。本篇文章将详细阐述在Mac环境下配置NDK的过程,...

    基于openssl的MD5实现

    在压缩包中的"app"文件可能是编译好的Android应用程序,其中集成了这个MD5实现。它可能包含一个C++模块,该模块使用了OpenSSL库来计算MD5值。这个模块可能有一个接口供Java层调用,比如一个名为`calculateMD5`的函数...

Global site tag (gtag.js) - Google Analytics