• 您身边的移动安全专家

    提供安全检测、安全加密、安全监测等一站式的移动安全服务
    免费咨询

    首页 / 新闻资讯 / 从0到1接入APK加固平台:Android Studio插件...

    从0到1接入APK加固平台:Android Studio插件配置与Jenkins自动化流水线搭建

    作者:奇安信安全加固公司 2026-05-19 09:32:41 0 次浏览

    一、痛点与解决方案:为什么需要自动化加固?

    手动上传APK到加固平台、等待加固、下载、重新签名,这套流程在频繁发版时足够让人崩溃。更麻烦的是,Debug包和Release包需要差异化处理——Debug包加固后无法调试,反而影响日常开发。

    从0到1接入APK加固平台:Android Studio插件配置与Jenkins自动化流水线搭建

    本文以360加固宝为例(其他平台如几维安全、阿里云mPaaS逻辑类似),提供一套可复用的自动化方案:Gradle插件自动上传 + Jenkins流水线集成 + 多环境差异化配置。

    从0到1接入APK加固平台:Android Studio插件配置与Jenkins自动化流水线搭建

    二、Android Studio侧配置:Gradle插件自动化

    2.1 引入加固插件

    在项目根目录的build.gradle中添加插件依赖:

    buildscript {    repositories {        mavenCentral()        google()        // 360加固宝Maven仓库        maven { url 'https://mirrors.aliyun.com/repository/public/' }    }    dependencies {        classpath 'com.android.tools.build:gradle:8.1.0'        // 360加固宝Gradle插件        classpath 'com.qihoo.jiagu:jiagu-gradle-plugin:1.0.0'    }}

    app/build.gradle中应用插件并配置:

    apply plugin: 'com.android.application'apply plugin: 'jiagu'jiagu {    // 360加固账号(从local.properties读取,避免提交到Git)    userName = project.hasProperty('JIAGU_USER') ? JIAGU_USER : ''    password = project.hasProperty('JIAGU_PASS') ? JIAGU_PASS : ''        // 签名配置(加固后自动重签名)    sign {        keystore = file('../keystore/release.jks')        keystorePassword = project.hasProperty('KEYSTORE_PASS') ? KEYSTORE_PASS : ''        keyAlias = project.hasProperty('KEY_ALIAS') ? KEY_ALIAS : ''        keyPassword = project.hasProperty('KEY_PASS') ? KEY_PASS : ''    }        // 多渠道配置    channels = ['huawei', 'xiaomi', 'oppo', 'vivo']        // 输出目录    outputDir = file('../build/jiagu')        // 加固选项(按需开启)    config {        // 代码混淆加密        isObfuscate = true        // SO文件加密        isSoEncrypt = true        // 资源加密        isResourceEncrypt = false  // 资源加密可能影响部分UI框架        // 防内存Dump        isAntiMemoryDump = true        // 防动态调试        isAntiDebug = true    }}

    2.2 差异化加固策略(Debug不加固/Release加固)

    Debug包不需要加固(加固后无法断点调试),Release包必须加固。通过buildTypes区分:

    android {    buildTypes {        debug {            minifyEnabled false            debuggable true            // Debug包跳过加固(通过gradle task依赖控制)        }        release {            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'            signingConfig signingConfigs.release        }    }}// 创建加固任务,仅在Release构建时执行task jiaguRelease(type: JiGuTask) {    onlyIf {        // 仅当构建的是Release变体时执行        gradle.startParameter.taskNames.any { it.contains('Release') }    }}// 让assembleRelease自动触发加固afterEvaluate {    tasks.findAll { task ->        task.name == 'assembleRelease'    }.each { assembleTask ->        assembleTask.finalizedBy(jiaguRelease)    }}

    2.3 多渠道打包与加固结合

    如果使用productFlavors管理渠道,加固插件通常支持渠道包自动处理。配置如下:

    从0到1接入APK加固平台:Android Studio插件配置与Jenkins自动化流水线搭建

    android {    flavorDimensions "market"    productFlavors {        huawei {            dimension "market"            applicationIdSuffix ".huawei"            versionNameSuffix "-HW"        }        xiaomi {            dimension "market"            applicationIdSuffix ".xiaomi"            versionNameSuffix "-XM"        }    }}jiagu {    // 动态获取渠道列表(从productFlavors读取)    channels = android.productFlavors*.name}

    重要说明:部分加固平台(如阿里云mPaaS)要求加固后再签名,且对minSdkVersion有要求——minSdkVersion推荐设置为23以下,否则需在application标签中添加android:extractNativeLibs="true"

    三、Jenkins自动化流水线搭建

    3.1 前提条件

    • Jenkins服务器已配置Android SDK、Gradle、JDK 17+
    • 加固平台的命令行工具(如360的jiagu.jar)已上传至Jenkins服务器
    • 签名证书和账号密码已配置为Jenkins凭证

    3.2 Pipeline脚本(Declarative Pipeline)

    pipeline {    agent { label 'android-builder' }        environment {        // 从Jenkins凭证读取敏感信息        JIAGU_USER = credentials('jiagu-username')        JIAGU_PASS = credentials('jiagu-password')        KEYSTORE_PASS = credentials('keystore-password')        KEY_ALIAS = credentials('key-alias')        KEY_PASS = credentials('key-password')                // 构建参数        BUILD_TYPE = params.BUILD_TYPE ?: 'release'        CHANNEL = params.CHANNEL ?: 'all'    }        stages {        stage('代码拉取') {            steps {                git branch: 'main', url: 'https://github.com/your-repo/app.git'            }        }                stage('环境准备') {            steps {                sh 'chmod +x gradlew'                // 下载依赖                sh './gradlew dependencies --no-daemon'            }        }                stage('构建未加固APK') {            steps {                script {                    if (env.CHANNEL == 'all') {                        sh "./gradlew clean assemble${BUILD_TYPE.capitalize()} --no-daemon"                    } else {                        sh "./gradlew clean assemble${env.CHANNEL.capitalize()}${BUILD_TYPE.capitalize()} --no-daemon"                    }                }            }        }                stage('APK加固') {            steps {                script {                    // 定位生成的APK文件                    def apkDir = "app/build/outputs/apk/${BUILD_TYPE}"                    def apkFile = findFiles(glob: "${apkDir}/*.apk")[0]                                        if (!apkFile) {                        error "未找到待加固的APK文件"                    }                                        // 调用加固命令行                    sh """                        java -jar /tools/jiagu/jiagu.jar -login ${JIAGU_USER} ${JIAGU_PASS}                        java -jar /tools/jiagu/jiagu.jar -importsign ${KEYSTORE_PATH} ${KEYSTORE_PASS} ${KEY_ALIAS} ${KEY_PASS}                        java -jar /tools/jiagu/jiagu.jar -config -analyse                        java -jar /tools/jiagu/jiagu.jar -jiagu ${apkFile.path} build/jiagu/ -autosign                    """                }            }        }                stage('重新签名(如需要)') {            steps {                script {                    // 部分加固平台加固后会移除签名,需重新签名                    sh """                        apksigner sign --ks ${KEYSTORE_PATH} \                            --ks-pass pass:${KEYSTORE_PASS} \                            --key-pass pass:${KEY_PASS} \                            --out build/jiagu/app-signed.apk \                            build/jiagu/app-release-jiagu.apk                    """                }            }        }                stage('归档产物') {            steps {                archiveArtifacts artifacts: 'build/jiagu/*.apk', fingerprint: true                // 上传至内部分发平台(如蒲公英、fir.im)                step([                    $class: 'PgyerPublisher',                    installApiKey: 'your-pgyer-api-key',                    filePath: 'build/jiagu/app-signed.apk'                ])            }        }    }        post {        always {            cleanWs()  // 清理工作空间        }        failure {            emailext (                subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",                body: "请检查Jenkins构建日志",                to: 'dev-team@company.com'            )        }    }}

    3.3 通用加固命令行模式(适用于各平台)

    不同加固平台的命令行调用方式略有差异,但核心流程一致:

    平台命令行示例
    360加固宝java -jar jiagu.jar -login
    java -jar jiagu.jar -jiagu input.apk output/ -autosign
    几维安全kiwi-cli -i input.apk -o output/ -mode virtual
    阿里云mPaaS通过API调用,或使用控制台上传(无公开CLI)
    网易易盾dun-cli -c config.json -i input.apk

    关键点:加固后的APK通常没有签名信息,必须重新签名才能安装。

    四、常见报错排查

    根据各平台官方文档和实际踩坑经验,整理以下高频问题:

    4.1 加固失败:Invalid APK

    错误码:2(网易易盾)

    原因

    • APK中的classes.dexAndroidManifest.xml文件损坏
    • APK本身未签名(加固平台要求输入APK必须是已签名的)

    解决:确保先执行assembleRelease生成已签名的APK,再加固。

    4.2 加固后闪退:Provider初始化问题

    现象:加固后首次启动崩溃,日志显示ContentProvider相关错误。

    原因:部分加固平台会修改AndroidManifest.xml中的Application类,导致ContentProvideronCreate被多次执行。

    解决

    • 确保Provider.onCreate()中的逻辑可以幂等执行
    • 如果使用ARouter,需要添加Gradle插件自动注册路由表
    // app/build.gradlebuildscript {    dependencies {        classpath "com.alibaba:arouter-register:1.0.2"    }}apply plugin: 'com.alibaba.arouter'

    4.3 加固后方法数超标(65K问题)

    错误码:18/19/20(网易易盾)

    原因:加固引擎向classes.dex中注入解密代码,导致方法数超过65535上限。

    解决

    • 启用MultiDex
    • 控制主dex方法数,在打包时设置--set-max-idx-number=64000预留空间

    4.4 CI/CD集成失败:找不到加固命令

    现象:Jenkins执行加固步骤时报java: command not foundjar包不存在

    原因:Jenkins节点的环境变量未配置,或加固工具路径错误。

    解决

    • 在Pipeline中使用tool指令指定JDK版本
    • 使用绝对路径引用jiagu.jar
    tools {    jdk 'JDK17'}

    4.5 加固后Google Play审核被拒

    原因:加固方案引入了敏感的动态加载行为,触发了Google的恶意软件检测算法。

    解决

    • 选择通过Google Play兼容性认证的加固方案
    • 加固后使用Play Console的预检工具测试
    • 避免过度加固(如代码动态解密、运行时反射)

    五、最佳实践总结

    1. 签名前置:加固前必须先签名,加固后再次签名,确保V1/V2/V3签名完整。
    2. 差异化策略:Debug包跳过加固,Release包强制加固,测试包可按需加固。
    3. 渠道包处理:建议在加固后再进行多渠道打包(部分平台支持一次加固、多渠道自动签名)。
    4. 回归测试:加固后必须在真机(特别是低端机型)上完整回归核心功能,重点关注热修复、升级、支付模块。
    5. 凭证保护:签名密码、加固账号通过Jenkins凭证或local.properties注入,绝不硬编码在代码中
    6. 版本追溯:加固后的APK命名规范建议包含版本号、渠道、加固时间戳。
    // APK命名示例outputFileName = "App_${flavor}_${buildType}_v${versionName}_${date}_jiagu.apk"

    这套方案已在我们多个项目中稳定运行,覆盖从开发调试到应用商店上架的完整链路。根据你的加固平台和CI/CD环境,适当调整命令行和参数即可复用。

    标签: 加固

    文章目录

    • 正在生成目录…