经常使用的总结:
debug 签名:
development/tools/make_key media '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key networkstack '/C=CN/ST=BeiJing/L=ChaoYang/O=/OU=xxx/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key platform '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key shared '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key testkey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
user签名:
development/tools/make_key media '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key networkstack '/C=CN/ST=BeiJing/L=ChaoYang/O=user/OU=Pwe/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key platform '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key shared '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key testkey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
ota:
../development/tools/make_key releasekey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=xxx/CN=xxx/emailAddress=cm@xxxx.com'
查看生成的格式文件:
keytool -printcert -file platform.x509.pem
使用signapk.jar 进行签名:android10:
java -Djava.library.path="out/host/linux-x86/lib64" -jar out/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 old.apk new.apk
android 11:
./soong/host/linux-x86/framework/signapk.jar
如何产生jsk (keystore)文件, 只做了debug 模式发的
./keytool-importkeypair -k test.jks -p android -pk8 platform.pk8 -cert platform.x509.pem -alias test
如何查看test.jks 是否正确:
keytool -list -v -keystore test.jks
Android studio 如何使用:
signingConfigs {
releaseConfig {
keyAlias 'test'
keyPassword 'android '
storeFile file('/home/xxx/tools/keystore/test.jks')
storePassword 'android '
}
}
AndroidManifest.xml的manifest节点中添加
android:sharedUserId=”android.uid.system”,
Android.mk中增加 LOCAL_CERTIFICATE := platform
APK中的META-INF/CERT.RSA
签名之后如何对RSA 进行查看,签名的信息,在android root目录
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
本文主要讲解签名的原因,签名怎么保证数据的正确,主要知识点
- 数据摘要(数据指纹,消息摘要)
- 签名文件和证书
- 签名Apk包与没有签名的APK 差异在哪里
- 如何对apk 进行签名
1-数据摘要
就是对一个数据源进行一个算法之后得到一个摘要,也叫作数据指纹,不同的数据源,数据指纹肯定不一样,就和人一样
消息摘要算法(Message Digest Algorithm)是一种能产生特殊输出格式的算法,其原理是根据一定的运算规则对原始数据进行某种形式的信息提取,被提取出的信息就被称作原始数据的消息摘要。
著名的摘要算法有RSA公司的MD5
算法和SHA-1
算法及其大量的变体。
- 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。
- 原始数据不同,消息摘要不相同
- 具有不可逆性
2-签名文件和证书
消息的发送者来说,先要生成一对公私钥对,将公钥给消息的接收者
- 提取原始消息提取消息摘要;
- 私钥加密消息摘要;
上面就是所原始信息的数字签名。【数字签名=私钥对[原始数据摘要]
】
消息的接受者来说,收到了:原始的消息内容+附加数字签名.
接收者收到内容:原始的消息内容+私钥对[原始数据摘要]
验证正确需要数据摘要算法+公钥
,公钥假设是正确的。
如何验证:数据摘要算法对内容提取摘要 对比
公钥解密签名
图示验证过程:
3-如何保证公钥是正确的
数字证书,一般包含以下一些内容:
- 证书的发布机构(Issuer)
- 证书的有效期(Validity)
- 消息发送方的公钥
- 证书所有者(Subject)
- 数字签名所使用的算法
- 数字签名 --》 数字证书也使用到了数字签名,只不过签名的内容是证书
公钥签发流程
上面核心内容就是申请者
提出申请公钥,公信力机构
使用自己的私钥对申请者
的公钥数字签名, 公信力机构的公钥是大家都知道的,因此成功后,申请者的client 端就可以通过公信力机构
获取, 以验证公钥的正确性。
上面的内容是我在理解HTTPS ,一直想不通的地方,现在终于想通了签发机构是如何发送公钥的。
其实app 的数字签名与上面的CA 机构的签名还是有点区别的。
APP 是如何保证签名流程的:
apk签名其实是对所有源文件单独计算摘要, 然后用私钥
加密摘要信息再得到一个加密串, 我们称之为
APK的签名. 你对源文件的修改都会导致签名的变化. 这个是为了验证apk没有被篡改.
app的升级和重新安装, 检测的并不是这个apk签名, 而是你的包名+私钥的摘要信息, 签名的keystore文件没有变, 私钥的摘要信息也就不会变了.
google APP store, 当开发者第一步开发的时候,就需要有自己的签名,私钥的摘要信息上传到goole APP store, 如果升级的时候, 私钥的摘要不一致肯定不能升级app 的上传,这里应该做了校验的。
4-签名Apk包与没有签名的APK 差异在哪里
源码位置:com/android/signapk/sign.java
Android签名apk之后,会有一个META-INF文件夹,这里有三个文件:
- MANIFEST.MF
- CERT.RSA
- CERT.SF
MANIFEST.MF是:
逐一遍历里面的所有条目,如果是目录就跳过,如果是一个文件,就用SHA1(或者SHA256)消息摘要算法提取出该文件的摘要然后进行BASE64编码后,作为“SHA1-Digest”属性的值写入到MANIFEST.MF文件中的一个块中。该块有一个“Name”属性,其值就是该文件在apk包中的路径。
CERT.SF:
逐条计算MANIFEST.MF文件中每一个块的SHA1,并经过BASE64编码后,记录在CERT.SF中的同名块中,属性的名字是“SHA1-Digest
CERT.RSA:
把之前生成的 CERT.SF文件, 用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入 CERT.RSA 中保存,还有私钥的摘要信息
5-如何对apk 进行签名
5.1生成签名文件
development/tools/make_key testkey '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
如何查看生成的platform.X509.pem:
build/target/product/security/platform.x509.pem
keytool -printcert -file platform.x509.pem
或者
openssl x509 -inform PEM -subject_hash_old -in platform.x509.pem -text
单独给APP签名方法:
java -Djava.library.path="out/host/linux-x86/lib64" -jar out/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 old.apk new.apk
APP签名之后,如何查看CERT.RSA 信息
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
6-Android OTA releasekey 替换
6.1生成key
系统默认的key如下,首先需要产生以下4种我们项目自己的OTA签名key文件,每一种类型的key都是成对生成的,.509.pem后缀名的是公钥,.pk8后缀名的是私钥。
testkey -- a generic key for packages that do not otherwise specify a key.
platform -- a test key for packages that are part of the core platform.
shared -- a test key for things that are shared in the home/contacts process.
media -- a test key for packages that are part of the media/download system.
将XXX替换为自己公司信息。
生成文件如下:
media.pk8 media.x509.pem platform.pk8 platform.x509.pem
releasekey.pk8 releasekey.x509.pem shared.pk8 shared.x509.pem
将生成的key 文件放到项目相关的目录下,针对Amlogic项目放到device/amlogic/p341/sign_keys。这样我们公司的key就生成了。
6.2.更改编译规则,使编译过程中使用我们新生成的key对OTA进行签名
首先在build/core/Makefile里搜索testkey, 查看testkey是怎么用到编译系统的,看到如下编译选项:
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/testkey)
BUILD_KEYS := test-keys
else
BUILD_KEYS := dev-keys
endif
继续查看DEFAULT_SYSTEM_DEV_CERTIFICATE
,可以看到在build/core/config.mk文件里有如下:
# The default key if not set as LOCAL_CERTIFICATE
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
endif
因此要想使用releasekey,只需要指定PRODUCT_DEFAULT_DEV_CERTIFICATE
的值即可,因此在device/amlogic/p341/p341.mk
中指定项目特定变量
PRODUCT_DEFAULT_DEV_CERTIFICATE := device/amlogic/p341/sign_keys/releasekey
同时在根据规则,在build/core/Makefile
改动如下:
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),device/amlogic/p341/sign_keys/releasekey)
BUILD_KEYS := release-keys
endif
6.3. Androoid.mk 使用platform 签名
对于apk的签名,系统会根据apk里指定的key进行签名。如果系统中的apk的android.mk中没有设置LOCAL_CERTIFICATE的值,就默认使用testkey。
ifeq ($(LOCAL_CERTIFICATE),)
LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
endif
private_key := $(LOCAL_CERTIFICATE).pk8
certificate := $(LOCAL_CERTIFICATE).x509.pem
而如果设置成:
LOCAL_CERTIFICATE := platform
就代表使用platform来签名,这样的话这个apk就拥有了和system相同的签名
如何产生jks文件,提供给android studio 开发使用,进行系统签名
jks文件:
第一种方式
https://github.com/chear/keytool-importkeypair
./keytool-importkeypair -k test.jks -p android -pk8 platform.pk8 -cert platform.x509.pem -alias test
最终会生成 test.jks
-k test.jks: test表示最终生成的jks的名字,可以自定义
android : 输入当前jks的密码,可以自定义。
alias test: test表示别名,可以自定义,建议和上面的jks一致。
第二种方式: 该方式作为记录,实际与第一种方式是想通的,可以看keytool-importkeypair 脚本
1、编译android源码。
2、cd build/target/product/security/
3、执行
openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
生成platform.pem文件
4、
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:123456 -name test
生成platform.p12文件,其中 "test" 为alias名(app添加签名要用到),"123456" 为密码。
5、执行
keytool -importkeystore -deststorepass test -destkeystore platform.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass test
生成platform.jks (app打签名最终用到的文件),
-deststorepass "123456" 设置的是这个签名的密码,
-src* 的其他参数都是从前面两个指令中生成的。
6、生成platform.jks
keytool -importkeystore -srckeystore platform.jks -destkeystore platform.jks -deststoretype pkcs12
说明:platform.jks 实际是含有了公钥与私钥, 这个是不能release给第三方的,只能给自己公司研发使用
思考:
-
一个数据内容使用一个签名就可以,一个app 使用一个签名就可以,如果重复签名会怎么样?
重复使用signapk 签名会覆盖,上次的签名失效,【没有使用studio 多次签名试过,看到有别名的可以有多个】
普通签名与系统签名的区别?
签名是保证数据不被改写
系统签名就是要获取一些系统权限,修改时间权限等等
普通签名仅仅保证数据正确,单存的app 开发,上传到APP store ,不需要获取修改系统的权限。app升级过程中,如何保证升级APP 数据是正确的?
数字签名 与公钥联合,配合私钥的数据摘要,android 升级过程进行了对比,如果在第一次安装设备时候就修改了数字签名,那么再次安装正确的app 不会成功。 因此老老实实从Apple store 下载,这样保证app 正确,没有打广告等https协议中的公钥,私钥处理方式,ssl 中公钥如何传递给使用者?
通过CA 公信力结构,公钥分发给使用者,ssl协议在协商过程使用非对称加密技术, 最后协商出对称秘钥进行通信,对称秘要没有在网络上传递, 是双方通过算法计算出来的。
7 设计原则与测试结果
7.1设计原则
签名文件规格:(device.mk设计参考之前的)
1)Userdebug 与user 区别
userdebug 系统platform.jks 有可能release 给别人,因此user版本设计成不一样的。
user 系统platform.jks 仅仅relase公司的app 开发人员
2)user 与ota ,只是ota 多了releaseky,其他文件都一样
7.2测试华为手机user version【开发者模式】:
debug app 可以正常安装, 在AndroidManifest.xml 添加了
android:sharedUserId="android.uid.system"
release apk(没有签名), 不能安装,【 在AndroidManifest.xml 添加了
android:sharedUserId="android.uid.system"
release apk(使用platform 签名[android10 google原生platformq签名]), 这种方式可以正常安装
release apk(使用platform 签名[自己制作android10platformq签名]), 这种方式可以正常安装
上面两种都可以安装,在运行的时候对系统权限的多种有所不同。release apk(使用platform 签名[自己制作android10platformq签名]), 这种方式可以正常安装,安装之后再次对APK 签名(使用原生签名文件), 发现CERT.RSA 签名文件失效, 不能再次安装,提示签名不匹配
Performing Streamed Install
adb: failed to install C:\Users\Desktop\old.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.example.demo signatures do not match previously installed version; ignoring!]
REF:
https://www.jianshu.com/p/76e5f5e64b85
https://developer.android.google.cn/studio/publish/app-signing
ota relase key 参考
下载文件地址:
git clone https://github.com/getfatday/keytool-importkeypair.git