android-apk签名
##APK Signe
签名是为了什么
为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性(如自动更新不会因为版本不一致而无法安装)。
###签名需要了解的知识点
- 数据摘要(数据指纹)、签名文件,证书文件
- jarsign工具签名和signapk工具签名
- keystore文件和pk8文件,x509.pem文件的关系
- 如何手动的签名apk
签名文件和证书
发送者:
1)对要发送的原始消息提取消息摘要;
2)对提取的信息摘要用自己的私钥加密。附加上自己的数字证书
接收者:
先使用CA公钥解开数字证书,获取发送者的公钥信息
1)对原始消息部分提取消息摘要,注意这里使用的消息摘要算法要和发送方使用的一致;
2)对附加上的那段数字签名,使用得到的公钥解密;
3)比较前两步所得到的两段消息是否一致。如果一致,则表明消息确实是期望的发送者发的,且内容没有被篡改过;相反,如果不一致,则表明传送的过程中一定出了问题,消息不可信。
数字证书用来保证公钥的可信性。
“证书中心”(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对请求者的公钥和一些相关信息一起加密,生成”数字证书”(Digital Certificate)。
数字签名和签名验证的大体流程:
将apk解压;
找到META-INF 下的.RSA文件;
进入cmd环境,进入.RSA文件文件所在路径,命令:
`keytool -printcert -file XXX.RSA`
即可查看签名信息。
### jarsign工具签名和signapk工具签名
jarsign工具签名时使用的是keystore文件
signapk工具签名时使用的是pk8,x509.pem文件
jarsigner -verbose -sigalg SHA1withDSA -digestalg SHA1 -keystore D:\jiangwei.keystore -storepass jiangwei D:\123.apk jiangwei |
Android 签名方法
apksign.jar由Android SDK提供
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk |
它接受一个PEM公钥文件,PK8私钥文件,对update.apk进行签名,签名后的文件保存到update_signed.apk。
openssl pkcs8 -topk8 -outform DER -in userkey.pem -inform PEM -out userkey.pk8 -nocrypt |
.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。
jarsinger是由JDK提供,使用方法如下:
jarsigner -verbose -keystore d:\\debug.keystore -signedjar update_signed.apk update.apk androiddebugkey -digestalg SHA1 -sigalg MD5withRSA -keypass android -storepass android |
其中:
-keystore表示keystore文件的路径
androiddebugkey 表示keystore中的一个别名
-digestalg表示摘要算法
-sigalg 表示签名算法
-keypass 表示别名密码
-storepass表示keystore密码
对一个APK文件签名之后,APK文件根目录下会增加META-INF目录,该目录下增加三个文件:
MANIFEST.MF |
其中.RSA文件还可能是.DSA文件,RSA与SF文件的文件名可以更改,但是它们的命名必须一样。
MANIFEST.MF中保存了APK里所有文件的SHA1校验值的BASE64编码,格式如下(一个文件对应一条记录):
Name: res/anim/abc_fade_in.xml |
SF文件里保存了MANIFEST.MF文件的SHA1校验值的BASE64编码,同时还保存了MANIFEST.MF中每一条记录的SHA1检验值BASE64编码,格式如下:
SHA1-Digest-Manifest: ZRhh1HuaoEKMn6o21W1as0sMlaU= |
CERT.RSA文件
这里我们看到的都是二进制文件,因为RSA文件加密了,所以我们需要用openssl命令才能查看其内容
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text |
CERT.RSA是一个满足PKCS7格式的文件。这里会把之前生成的 CERT.SF文件, 用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入 CERT.RSA 中保存。
###名词解释
####CSR
- Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好.做过iOS APP的朋友都应该知道是怎么向苹果申请开发者证书的吧.
查看的办法:
openssl req -noout -text -in my.csr |
(如果是DER格式的话照旧加上-inform der,这里不写了)
####PEM文件(.pem)
PEM是Privacy Enhanced Mail的缩写
PEM说明该文件是标准X.509证书文件,编码格式为PEM编码。
解密私钥
openssl rsa -in userkey.pem -out userPri.pem |
####X.509
X.509 不是证书文件,是一种证书标准。定义证书文件中结构和内容
###证书编码的转换
- PEM转为DER
openssl x509 -in cert.crt -outform der -out cert.der |
DER转为PEM
openssl x509 -in cert.crt -inform der -outform pem -out cert.pem |
(提示:要转换KEY文件也类似,只不过把x509换成rsa,要转CSR的话,把x509换成req…)
PEM,PK8转为key store
使用下面的工具
https://github.com/getfatday/keytool-importkeypair
./keytool-importkeypair -k debug.keystore -p android -pk8 ./userkey.pk8 -cert ./SuoErSi_USER.crt -alias userkey |
列出keystore存在的所有证书
keytool -list -v -keystore keystore.jks
JDK中keytool常用参数说明(不同版本有差异,详细可参见【附录】中的官方文档链接): |