android gradle 自动360加固apk

1,666 阅读3分钟

gradle 添加360加固apk包task

360 加固本身可以设置渠道包和重新签名。 本脚本没有使用360的设置渠道包和重新签名功能, 渠道设置是直接在gradle.build里面通过productFlavors设置的。

如果要做持续集成, 可以去掉加固完成后打开文件夹的操作

环境准备

  1. 在项目根目录, 也就是build.gradle所在路径创建key.properties文件, 在文件里面配置
storePassword=你的密码
keyPassword=你的密码
keyAlias=你的别名
storeFile=签名证书的路径
  1. 将360加固工具中的jiagu文件夹也拷贝到项目根目录, 并添加jiagu/config/jiagu.properties文件,文件中配置360加固的用户名和密码
jiaguUsername= 用户名
jiaguPassword= 密码
  1. 将jiagu文件夹和key.properties添加到.gitignore文件中去,避免将加固的用户名密码上传到仓库

脚本:

脚本可直接写在build.gradle里面, 也可以新建一个gradle文件, 然后在build.gradle文件中通过apply from的方式引入

//签名的key的配置
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

//360加固的账号配置
def jiaguProperties=new Properties()
def jiaguPropertiesFile=rootProject.file('jiagu/config/jiagu.properties')
if(jiaguPropertiesFile.exists()){
    jiaguProperties.load(new FileInputStream(jiaguPropertiesFile))
}

def executeCmd(String cmd){
    println("执行命令:${cmd}")
    exec {
        workingDir = './'
        def commands = []
        commands << 'cmd'
        commands << '/c'
        commands << cmd
        commandLine = commands
    }

}

def openWinFolder(String path){
    "explorer ${path}".execute()
}

task reinforceApp(dependsOn:'assembleRelease'){
//task reinforceApp(){
    group "jiaGuApk"
    doLast {
        println "360加固 begin"

        // assembleRelease 生成的apk的路径, 只加固release 包
        def apkOutputPath = getBuildDir().getAbsolutePath() + File.separator + "outputs" + File.separator+"apk"
				
				//加固后的apk输出路径
        String apkJiaguPath=getBuildDir().getAbsolutePath() + File.separator + "outputs" + File.separator+"jiagu"

				//清空上一次的加固结果
        File apkJiagu=new File(apkJiaguPath)
        apkJiagu.deleteDir()
        apkJiagu.mkdirs()

        
        File apkOutput=new File(apkOutputPath)
        if(!apkOutput.exists()){
           return
        }
			
				//列出渠道文件夹
        File[] flavors=apkOutput.listFiles(new FileFilter() {
            @Override
            boolean accept(File pathname) {
                return pathname.isDirectory()
            }
        })
				
				//登陆360加固
        String cmdBase="java -jar ${getRootDir()}${File.separator}jiagu${File.separator}jiagu.jar"
        String cmdLogin="${cmdBase} -login ${jiaguProperties['jiaguUsername']}  ${jiaguProperties['jiaguPassword']} "
        executeCmd(cmdLogin)

        for(File flavor:flavors){
            File releaseFile=new File(flavor.getAbsolutePath()+File.separator+"release")
            if(releaseFile.exists()){
               File[] apkFiles= releaseFile.listFiles(new FilenameFilter() {
                    @Override
                    boolean accept(File dir, String name) {
                        return name.endsWith(".apk")
                    }
                })
                if(apkFiles.length>0){
                    println("开始加固${flavor}")
                    File apkFile=apkFiles[0]
                    String apkName=apkFile.getName()
                    String apkFilePath=apkFile.getAbsolutePath()
                    String cmdJiagu ="${cmdBase} -jiagu   ${apkFilePath}  ${apkJiaguPath}"
                    executeCmd(cmdJiagu)

                   String[] jiaguNames= apkJiagu.list(new FilenameFilter() {
                        @Override
                        boolean accept(File dir, String name) {
                            return name.startsWith(apkName.substring(0,apkName.length()-4))
                        }
                    })

                    String jiaguApkName=jiaguNames[0]
                    String apkJiaguAndSignPath="${apkJiaguPath}${File.separator}signed_${jiaguApkName}"
										
										//因为360加固会去掉签名信息, 因此需要重新签名
                    String key_path="${rootProject.file('app').getAbsolutePath()}${keystoreProperties['storeFile']}"
                    String cmdSign="jarsigner -verbose -keystore ${key_path} -signedjar ${apkJiaguAndSignPath} ${apkJiaguPath}${File.separator}${jiaguApkName} ${keystoreProperties['keyAlias']} -storepass ${keystoreProperties['keyPassword']}"
                    executeCmd(cmdSign)
                }
            }
        }
				//执行完成后,打开加固文件夹, 如果是做持续集成, 去掉这一步
        openWinFolder(apkJiaguPath)
        println "360加固 end"
    }
}

由于最近360限制了个人账号的加固方式,加上之前那种一个渠道一个渠道加固的模式比较费时费力, 可以按下面方式调整成了使用360的多渠道加固

  • 脚本主体还是不变, 添加一个多渠道配置文件channel.txt, 如下所示:
# 第一个值 CHANNEL_NAME 就是AndroidManifest.xml 里面 meta-data 的name, 后面接着的是渠道的描述,最后的值就是 meta-data的value
CHANNEL_NAME xx市场 渠道的值
CHANNEL_NAME xx1市场 10001
  • 修改脚本 在执行加固脚本之前,执行导入多渠道配置的命令
 //导入渠道配置的命令
                String cmdLoadChannel="${cmdBase} -importmulpkg ${getRootDir()}${File.separator}channel.txt"
                println('导入渠道模板')
                executeCmd(cmdLoadChannel)

如果需要帮忙签名的话, 还需要执行导入证书的命令

 //导入签名证书的命令
                String cmdLoadSign="${cmdBase}  -importsign ${rootProject.file('app').getAbsolutePath()}${keystoreProperties['storeFile']}  xxpassword  xxalias  xxpassword"
                executeCmd(cmdLoadSign)

加固的命令也要修改一下,在之前的基础上加上 自动多渠道-automulpkg 和自动签名-autosign , 如果不需要自动签名 , 就不使用-autosign

 //加固的命令
                String cmdJiagu = "${cmdBase}  -jiagu  ${apkFilePath}  ${apkJiaguPath}  -autosign -automulpkg"
                executeCmd(cmdJiagu)

由于我使用了自动签名, 所以之前的签名步骤的脚本就不需要了

//签名 ,废弃, 用360签名算了
//                String[] jiaguNames = apkJiagu.list(new FilenameFilter() {
//                    @Override
//                    boolean accept(File dir, String name) {
//                        return name.startsWith(apkName.substring(0, apkName.length() - 4))
//                    }
//                })
//
//                String jiaguApkName = jiaguNames[0]
//                String apkJiaguAndSignPath = "${apkJiaguPath}${File.separator}signed_${jiaguApkName}"
//
//                String key_path = "${rootProject.file('app').getAbsolutePath()}${keystoreProperties['storeFile']}"
//                String cmdSign = "jarsigner -verbose -keystore ${key_path} -signedjar ${apkJiaguAndSignPath} ${apkJiaguPath}${File.separator}${jiaguApkName} ${keystoreProperties['keyAlias']}  -storepass ${keystoreProperties['keyPassword']}"
//                executeCmd(cmdSign)