【篇三】通过Jenkins打包时自动加固APK

2017/4/26 12:28 下午 posted in  持续集成  

这里加固使用了360加固保。

  • 官网文档戳这里
  • 加固保客户端:官网提供了Windows、Mac的加固保客户端下载地址,也可通过网页在线加固。Linux版加固保客户端,由于一直未维护,官网未提供下载地址。
  • 获取Linux版加固保客户端:通过邮箱(360jiagubao@360.cn)或QQ群(群号:93070407)索取。【实测邮箱无人回复,QQ群比较靠谱】

1. 打包自动加固原理

在Jenkins打包服务器(CentOS)上安装Linux版加固保客户端,该客户端支持命令行方式调用,因此我们可以通过编写shell脚本并将该脚本置于Jenkins打包的流程中,以实现打包后自动加固的需求。

2. 安装加固保客户端

将Linux版加固保客户端解压到打包服务器某一目录下即可。

3. 编写加固脚本

该脚本用于调用Linux版加固保,为保证通用性,我们在调用该脚本时支持传递相关参数。

支持的参数(调用脚本时需按顺序提供):

  1. keystore_path:签名文件路径
  2. keystore_password:签名文件密码
  3. keystore_alias:别名
  4. keystore_alias_password:别名密码
  5. input_apk_path_filter:待加固apk路径,支持通配符
  6. output_apk_dir:加固完成后apk输出目录
  7. enhancement_service:增加服务,可选“-x86”、“-update”、“-crashlog”。若不需要增强服务,请留空

加固保客户端的安装位置、用户名、密码,配置在脚本中,请根据实际情况进行配置。

然后将该脚本放到打包服务器的某一目录下,注意为该脚本添加Jenkins用户的可执行权限(如设置成755)

#!/bin/bash
# 自定义打印函数,-e支持输出转义字符,$@所有参数
print(){
    echo -e "\n\n----->"$@
}
# 筛选出最后修改的1个文件,-t按时间降序排列
latestFile(){
    ls -t "$@" | head -1
}

print '【初始化】'
## 常量配置开始 ##
# 用户名、密码
user_name='your-jiagubao-user-name'
password='your-jiagubao-password'

# keystore
keystore_path=$1
keystore_password=$2
keystore_alias=$3
keystore_alias_password=$4

# 输入/输出apk
input_apk_path_filter=$5
input_apk_path=$(latestFile $input_apk_path_filter)

output_apk_dir=$6
output_apk_name_filter='*jiagu_sign.apk'
output_apk_path_filter="${output_apk_dir}${output_apk_name_filter}"

print "【待加固apk】${input_apk_path}"

# 增强服务
enhancement_service=${7:-''} # 若未向脚本提供该参数,则默认为空字符串''

# 加固保根目录
jiagubao_dir='/dir/where/your/jiagu/script/locates/' # 目录包含末尾斜线
## 常量配置结束 ##

cd $jiagubao_dir

print "【进入目录】 $PWD"

# 1. 登录
print "【登录】"
java/bin/java -jar jiagu.jar -login $user_name $password
# 2. 导入keystore信息
print "【导入keystore信息】"
java/bin/java -jar jiagu.jar -importsign $keystore_path $keystore_password $keystore_alias $keystore_alias_password
# 3. 配置增加服务,若不需要则跳过
if [ "$enhancement_service" != '' ]
then
    print "【配置增强服务】"
    java/bin/java -jar jiagu.jar -config $enhancement_service
fi
# 4. 加固
print "【加固】"
java/bin/java -jar jiagu.jar -jiagu $input_apk_path $output_apk_dir -autosign
# 5. 输出结果
output_apk=$(latestFile $output_apk_path_filter)
print "【加固完成apk】${output_apk}"
exit

4. 编写Jenkins中用于调用加固脚本的shell脚本

该脚本与每个待加固的APP对应,用于调用步骤3中编写的脚本。以下参数需要根据实际情况进行配置:

  1. Debug、Release版的签名文件信息
  2. 待打包的apk所在目录
  3. 加固前/后的apk路径过滤器
  4. 增强服务

脚本修改完后,需要在Jenkins中每个APP Job的“构建”下添加Execute shell,并将脚本内容添加到Command文本框中。
注意:该Execute shell应该在打包apk完成后执行,即在Invoke Gradle script之后。

# 【加固相关】

set +x # 抑制输出脚本内容

# 签名用keystore
dbg_ks="${PWD}/apk/debug.keystore"
dbg_ks_psw='xxx'
dbg_ks_alias='debug'
dbg_ks_alias_psw='xxx'

rlse_ks="${PWD}/apk/xxx"
rlse_ks_psw='xxx'
rlse_ks_alias='xxx'
rlse_ks_alias_psw='xxx'

# apk目录
apk_dir="${PWD}/app/build/outputs/apk/" # 目录包含末尾斜线

# 加固前/后apk path filter,用于获取满足filter的最后修改的apk
input_apk_path_filter="${apk_dir}your-apk-name*.apk"
output_apk_path_filter="${apk_dir}your-apk-name*jiagu_sign.apk"

# 增强服务,可选“-x86”、“-update”、“-crashlog”,如不需要增强服务,请留空
enhancement_service=''

if [ ${BuildType} == 'Release' ]
then
    # 参数:keystore路径、keystore密码、keystore别名、keystore别名密码、待加固apk路径filter、加固后apk输出目录、增强服务
    bash +ex /path/to/jiagu/script/on/server/xxx.sh $rlse_ks $rlse_ks_psw $rlse_ks_alias $rlse_ks_alias_psw $input_apk_path_filter $apk_dir $enhancement_service
else
    bash +ex /path/to/jiagu/script/on/server/xxx.sh $dbg_ks $dbg_ks_psw $dbg_ks_alias $dbg_ks_alias_psw $input_apk_path_filter $apk_dir $enhancement_service
fi

# 加固后的apk路径
output_apk_path=$(ls -t $output_apk_path_filter | head -1)