Android so库防客户端破解的解决方案

本文探讨了Android客户端的安全性问题,尤其是针对SO库的保护措施。通过将关键信息放入SO库并校验签名,提高破解难度。介绍了在C/S协议安全、SO库校验签名的方法,包括在JNI层实现签名验证,并详细讲解了编译过程及Gradle配置,以确保不同版本的SO库执行相应业务逻辑。同时分享了JNI开发的一些实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

随着移动互联网的发展,移动应用的安全问题越来越突显,特别是涉及到钱相关的产品,前段一段时间,我们的Android客户端产品被人破解了,修改了一些代码,重新打包签名后,就可以免费获得资源,对我们的收入造成了一些影响,移动产品安全性就不得不提重视,安全性这个话题很大,包括客户端、服务端、数据存储、协议等很多方面,这里只是从客户端的角度来讨论一上如何保证客户端产品的安全性,抛砖引玉,也希望大家多提意见和建议。

下面主要从以下几个方面来展开讨论:

C/S协议安全

在不使用https的前提下,要保证C/S协议的安全,一般都会进行参数的校验,以及参数加密,客户端和服务端会约定一个固定的字符串作为key,对于客户端来说,这个key应该放到哪里?最早之前,我们是直接放到Java代码中,这样可以说没有什么安全性,后来为了稍微更加安全一点,把这些key都统一放到so库中实现,虽然也不能保证绝对安全,但起码可以增加破解的难度。

你肯定要说,如果这样做,就会有一个问题,如果别人把so拿出来,在直接调用这些native接口,也同样可以获得key,所以也同样不安全,怎么办呢?

能不能让 so 库只能在我们自己的app运行,别人调用就是砖头呢?

各位看官,接着往下看。

so库校验签名

一般的情况下,都会在 Application.onCreate() 方法里面检查当前应用的签名是否合法,如果不合法就直接退出,这种情况其实无法正在防止破解,因为破解的可以找到调用入口,把相应的代码删除,所以这样方法也就失效了,那有没有更好的方案呢?

想到的一种思路就是,so库本身就具体签名校验的机制,当so库被加载时 (JNI_OnLoad()方法),如果签名不合法,直接失败,so库根本加载不起来。

大概的思路如下代码所示:

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if (vm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    LOGI("Library JNI_OnLoad begin =========");

  if (checkSignature(env) != JNI_TRUE) {
            LOGE("    The app signature is NOT correct, please check the apk signture. ");
            LOGI("Library JNI_OnLoad end ===========");
            return -1;
    } else {
            LOGI("    The app signature is correct.");
    }

    LOGI("Library JNI_OnLoad end ===========");

    return JNI_VERSION_1_6;
}
复制代码

说明:这里有一个问题,需要注意,在开发过程中,我们不需要检查签名的合法性,只有在release版本才检查,所以上述逻辑还再完善,需要添加上DEBUG和RELASE的判断。

要怎么判断呢?我目前的思路是通过宏来判断,如果定义了宏并且为JNI_TRUE的话,就认为是release版本。

以下是完整的实现:

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if (vm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    LOGI("Library JNI_OnLoad begin =========");

    // RELEASE_MODE这个宏是通过编译脚本设定的,如果是release模式,
    // 则RELEASE_MODE=1,否则为0或者未定义
#ifdef RELEASE_MODE
    if (RELEASE_MODE == 1) {
        // 检查当前应用的签名是否一致,如果不签名不一致的话,则直接退出
        if (checkSignature(env) != JNI_TRUE) {
            LOGE("    The app signature is NOT correct, please check the apk signture. ");
            LOGI("Library JNI_OnLoad end ===========");
            return -1;
        } else {
            LOGI("    The app signature is correct.");
        }
    } 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值