一、背景
关于android应用的签名及其原理,很多文章都有讲述,无意重复赘述。
本文紧接上文,站在运维的角度,对开发是透明的。
但是它又和gradle build 构建动作是紧密相关的。
第一步使用jdk的keytool生成证书文件,第二步调用android构建工具apksigner,对构建好的apk文件进行签名。(参考链接地址:manually-signing-the-apk )
二、生成keystore证书
1、手动生成keystore证书
$ keytool -genkeypair -v -keystore xample.keystore -alias publishingdoc -keyalg RSA -keysize 2048 -validity 10000
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: Ham Chimpanze
What is the name of your organizational unit?
[Unknown]: NASA
What is the name of your organization?
[Unknown]: NASA
What is the name of your City or Locality?
[Unknown]: Cape Canaveral
What is the name of your State or Province?
[Unknown]: Florida
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=Ham Chimpanze, OU=NASA, O=NASA, L=Cape Canaveral, ST=Florida, C=US correct?
[no]: yes
Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days
for: CN=Ham Chimpanze, OU=NASA, O=NASA, L=Cape Canaveral, ST=Florida, C=US
Enter key password for <publishingdoc>
(RETURN if same as keystore password):
Re-enter new password:
[Storing xample.keystore]
这是手动生成keystore证书文件,属于交互式的操作。
当使用shell命令生成keystore证书文件时,需进行适当的转换。
2、shell命令生成keystore证书
/opt/keystore.sh ${apkName} 证书文件名与apk的名称保持一致,别名是publishingdoc,密码是123456hello
expect <<!
spawn keytool -genkeypair -v -keystore $1.keystore -alias publishingdoc -keyalg RSA -keysize 2048 -validity 10000 -keystore ./$1.keystore
expect "Enter keystore password:"
send "123456hello\r"
sleep 1
expect "Re-enter new password:"
send "123456hello\r"
sleep 1
send "Ham Chimpanze\r"
sleep 1
send "NASA\r"
sleep 1
send "NASA\r"
sleep 1
send "Cape Canaveral\r"
sleep 1
send "Florida\r"
sleep 1
send "US\r"
sleep 1
send "yes\r"
sleep 1
send "\r"
sleep 1
expect eof
!
sleep 1
如此,便不需要人工与之交互,就可以生成keystore证书文件了。
- 生成的xxx.keystore文件,存在于jenkins服务器的目录下
三、android应用程序的配置
前文说了,开发是不能知道keystore文件信息的,生成过程交由jenkins服务器完成。
而gradle打包完成后,对应用签名的时候,是需要知道keystore证书所在以及密码。
所以,我们新建一个properties配置文件,jenkins服务器负责写入该配置文件,android应用程序只需要读取该配置文件。
配置文件apk.properties的格式如下:
## xxx是应用名称
APK_NAME=xxx.apk
APK_DIR=/opt/apks
STORE_FILE=/opt/keystore/xxx.keystore
STORE_PASSWORD=123456hello
KEY_ALIAS=publishingdoc
KEY_PASSWORD=123456hello
1、android代码
- apk.gradle
- build.gradle
android {
signingConfigs {
release {
}
}
buildTypes {
debug {
# 编译debug版本时,暂不签名
}
release {
# 编译release版本时,自动签名
signingConfig signingConfigs.release
}
}
}
2、properties配置文件
这里想补充一下,写入properties配置文件的两种方式:
- 简单粗暴地拼接文本内容
- 基于模板的变量替换
先创建一个模板文件,然后对其变量进行替换。
cp apk.properties.tpl apk.properties
# 替换变量的示例
sed -i -e "s|APK_NAME=|APK_NAME=$1.apk|" apk.properties
sed -i -e "s|STORE_FILE=/opt/keystore/|STORE_FILE=/opt/keystore/$1.keystore|" apk.properties
四、总结
android应用程序的打包,总是绕不开应用签名。
本文仅从运维的角度,梳理了其如何生成和使用的步骤。