数字签名简介
数字签名技术是将信息摘要用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的信息摘要,然后接收者用相同的Hash函数对收到的原文产生一个信息摘要,与解密的信息摘要做比对。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改;不同则说明信息被修改过,因此数字签名能保证信息的完整性。并且由于只有发送者才有加密摘要的私钥,所以我们可以确定信息一定是发送者发送的。
apk为什么需要数字签名
在安装Apk时,同样需要确保Apk来源的真实性,以及Apk没有被第三方篡改,Android签名机制是对APK包完整性和发布机构唯一性的一种校验机制。Apk中除签名文件外有任何修改,都会导致这个加密信息和无效,Android系统在安装Apk进行签名校验时就会不通过,从而保证了安全性。
apk文件组成
// 保存应用程序签名信息和校验信息
META-INF
// 未编译的资源文件
res
// apk封面信息,四大组件,权限等相关信息
AndroidManifest.xml
// 字节码文件
classes.dex
// 编译后的资源文件
resources.arsc
META-INF
1.MANIFEST.MF
遍历apk包中所有文件,对非文件夹、非签名文件的文件,逐个生成SHA1数字签名信息,再用Base64进行编码。
之后生成的签名写入MANIFEST.MF文件。
2.CERT.SF
对MANIFEST.MF中的每一条SHA1数字签名信息,使用SHA1-RSA算法,用私钥进行签名。
3.CERT.RSA
在CERT.RSA文件中保存公钥、所采用的加密算法等信息。
CERT.SF中的SHA1-Digest加密信息是通过MANIFEST.MF中的SHA1-Digest信息和私钥加密生成的,可以通过对应CERT.RSA中的公钥解密
MANIFEST.MF
Name: AndroidManifest.xml
SHA1-Digest: k7/ceeg9oGbaVce2ryTbxHcvu0U=
CERT.SF
Name: AndroidManifest.xml
SHA1-Digest: HlJUVC3qEiO1JHqvz+OzLKAM/p8=
签名过程
为APK签名
使用 release.jks(密钥库中唯一的密钥)为 APK 签名
apksigner sign --ks release.jks app.apk
使用私钥和证书(存储为不同的文件)为 APK 签名
apksigner sign --key release.pk8 --cert release.x509.pem app.apk
signapk.jar签名
java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk
什么是.pem和.pk8文件
.pem
在android对apk签名的时候,.pem这种文件就是一个X.509的数字证书,里面有用户的公钥等信息,是用来解密的。文件格式里面不仅可以存储数字证书,还能存各种key。
.pk8
以.pk8为扩展名的文件,应该和PKCS #8是对应的,用来保存private key。
转换平台签名命令
// https://github.com/getfatday/keytool-importkeypair
./keytool-importkeypair -k platform.jks -p platform -pk8 platform.pk8 -cert platform.x509.pem -alias platform
./keytool-importkeypair -k ./platform.keystore -p platform -pk8 platform.pk8 -cert platform.x509.pem -alias platform
pem和pk8文件转jks
// 1将pk8 转成pem 格式文件
openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt
// 2生成pk12 文件
openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name android
// 3输出jks文件
keytool -importkeystore -destkeystore ${filename}.jks -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass ${password}
jks转pem和pk8
// 1
keytool -importkeystore -srckeystore ${filename}.jks -destkeystore ${xxx}.p12 -srcstoretype jks -deststoretype PKCS12
// 2
openssl pkcs12 -in ${xxx}.p12 -nodes -out ${xxx_all}.rsa.pem -password pass:password
// 3
openssl pkcs12 -in ${xxx}.p12 -nodes -nokeys -out ${xxx}.x509.pem -password pass:${password}
// 4
openssl pkcs12 -in ${xxx}.p12 -nodes -cacerts -out ${xxx}.rsa.pem -password pass:${password}
// 5
openssl pkcs8 -topk8 -outform DER -in ${xxx}.rsa.pem -inform PEM -out ${xxx}.pk8 -nocrypt
查看签名信息
keytool -list -v -keystore ${filename}.jks