什么是 Google Play Protect ?
Android
端有害软件查杀功能组件,类似于Windows
端的Windows
安全中心。主要用于查杀sideload
(也就是我们通常说的apk
包)的应用,GPP(Google Play Protect)
认为Google Play
的审核是靠谱的,所以不会怎么去动在架GP
包。
不知道各位小伙伴有没有在开启谷歌服务的设备安装Apk时,遇到过下面这种Harmful app blocked
的提示?
领导一开始让我解决这个问题,我测试了无数次,在不同的手机有的设备会出现,有的设备不会出现,我是丈二和尚摸不着头脑,一脸懵逼!经过一段时间的测试,这个问题就被搁置了。
直到后来在网上看到有文章介绍 套Android
系统组件的签名可以规避Google Play Protect
拦截应用 的方案,于是就开始了尝试。
一、制作系统签名
签名文件
签名文件需要用到的文件有两个platform.pk8
和platform.x509.pem
,由于我们的应用不属于定制主板开发,因此使用Android
源码的这两个文件就行。 这里我直接通过ChatGPT
找到了AOSP
镜像在GitHub
上的仓库,进去搜索就得到了我需要的文件,然后下载这两个文件到本地待使用。
签名工具keytool-importkeypair
签名工具也可以直接从GitHub
上面下载,快捷访问keytool-importkeypair
注意事项:下载的文件名称应该同网上的文件名称一致,我本地下载下来后,发现后缀会自动加一个txt,如果你也有的话,需要手动去掉。
签名方法
第一步
现在你已经有签名文件platform.pk8
和platform.x509.pem
,签名工具文件keytool-importkeypair
,先将他们放在同一个文件夹。为了方便管理,最好是单独在项目根目录下创建文件夹keystores
第二步
在文件夹keystores
下创建signature.sh
脚本文件,脚本文件内容如下:
sh
sh keytool-importkeypair -k ./xxx.jks -p myjks -pk8 platform.pk8 -cert platform.x509.pem -alias signApk
指令详解:
-k ./xxx.jks
------./xxx.jks
指输出的签名文件地址-p myjks
------myjks
签名文件密码-alias signApk
------signApk
签名文件别名- 这里的签名文件密码属于
storePassword
,默认情况下storePassword
和别名的keyPassword
属于同一个
第三步
在AndroidStudio
中可以打开脚本文件,点击左上角的绿色三角符号运行脚本
当然,也可以通过其它方式来运行脚本文件。如果是在windows
下的话,双击脚本文件便可以得到运行;如果是在Linux
环境下,可直接执行。有疑问可以问问大模型。
脚本执行成功后就可以得到系统签名了。
storePassword
和keyPassword
补充事宜
如果你需要分别设置密钥库密码和密钥条目的密码,可以使用以下步骤:
1.创建密钥库(带密钥库密码):
sh
keytool -genkeypair -alias tempAlias -keyalg RSA -keysize 2048 -keystore my-release-key.jks -storepass storePassword -validity 10000
这里会提示你输入密钥条目的密码(keyPassword
),可以与密钥库密码(storePassword
)不同。
2.导入私钥和证书:
使用 keytool-importkeypair
时,如果工具支持单独的密钥条目密码,你可以设置两个密码。假设你的 keytool-importkeypair
脚本不支持单独指定密钥条目密码,你可以手动创建密钥库,然后导入私钥和证书:
sh
openssl pkcs8 -topk8 -inform PEM -outform DER -in platform.pk8 -out platform.der -nocrypt
keytool -importkeystore -deststorepass storePassword -destkeypass keyPassword -destkeystore my-release-key.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass keyPassword -alias signApk
这将需要你先将私钥和证书转换为PKCS12
格式,然后再导入到JKS
中。
实际操作示例
1. 创建带有密钥库密码的密钥库:
sh
keytool -genkeypair -alias tempAlias -keyalg RSA -keysize 2048 -keystore my-release-key.jks -storepass myjks -keypass mykeypass -validity 10000
2. 删除临时密钥条目(如果你只想保留导入的密钥):
sh
keytool -delete -alias tempAlias -keystore my-release-key.jks -storepass myjks
3. 使用转换和导入:
sh
openssl pkcs8 -topk8 -inform PEM -outform DER -in platform.pk8 -out platform.der -nocrypt
openssl pkcs12 -export -in platform.x509.pem -inkey platform.der -out platform.p12 -name signApk -passout pass:mykeypass
keytool -importkeystore -deststorepass myjks -destkeypass mykeypass -destkeystore my-release-key.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass mykeypass -alias signApk
通过这些步骤,你可以分别设置密钥库密码(storePassword
)和密钥条目密码(keyPassword
)。在上面的例子中,myjks
是密钥库密码,而 mykeypass
是密钥条目的密码。
系统签名的使用和解惑
使用签名
上面制作好了系统签名后,就可以替换项目里面的签名文件了。
groovy
signingConfigs{
...
debug{
storeFile file("../sign/system.jks")
storePassword "harmful"
keyAlias "harmful"
keyPassword "harmful"
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
...
}
运行之后确实没有上面Harmful app blocked
的弹窗提示了
分析签名
那么系统签名究竟做了什么呢?
查看系统签名文件
sh
keytool -list -v -keystore AndroidOSSign.jks -alias androidOSSign
AndroidOSSign.jks
签名文件androidOSSign
别名
使用上面的命令后,会要求输入密码,输入密码后就可以看到下面的信息了
ruby
别名: androidOSSign
创建日期: 2024年6月7日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
发布者: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
序列号: b3998086d056cffa
生效时间: Wed Apr 16 06:40:50 CST 2008, 失效时间: Sun Sep 02 06:40:50 CST 2035
证书指纹:
SHA1: 27:19:6E:38:6B:87:5E:76:AD:F7:00:E7:EA:84:E4:C6:EE:E3:3D:FA
SHA256: C8:A2:E9:BC:CF:59:7C:2F:B6:DC:66:BE:E2:93:FC:13:F2:FC:47:EC:77:BC:6B:2B:0D:52:C1:1F:51:19:2A:B8
签名算法名称: MD5withRSA(禁用)
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 4F E4 A0 B3 DD 9C BA 29 F7 1D 72 87 C4 E7 C3 8F O......)..r.....
0010: 20 86 C2 99 ...
]
[EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US]
SerialNumber: [ b3998086 d056cffa]
]
#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen: no limit
]
#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4F E4 A0 B3 DD 9C BA 29 F7 1D 72 87 C4 E7 C3 8F O......)..r.....
0010: 20 86 C2 99 ...
]
]
Warning:
证书 使用的 MD5withRSA 签名算法被视为存在安全风险而且被禁用。
我们重点关注一下所有者和发布者的信息:
ini
所有者: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
发布者: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
所有者
(Owner
) 和发布者
(Issuer
) 字段包含以下信息:
CN
(Common Name
):通常是个人的姓名或服务器名称。OU
(Organizational Unit
):组织单位。O
(Organization
):组织名称(公司)。L
(Locality
):城市或地方。ST
(State
):州或省。C
(Country
):国家。- 在自签名证书中,所有者和发布者是同一个实体。这意味着证书是由它所代表的实体自己签署的。自签名证书的所有者和发布者字段内容是相同的。
手动创建系统签名
看来系统签名主要是对所有者和发布者的信息进行了处理,那么我们可以自己进行设置吗?
当然,我们也可以根据上面的信息手动创建一个自签名,也可以得到和系统签名一个效果。
综上,我们基本上就可以解决签名的问题了。
但是,还有最后一个问题:
这个时候发现好像系统签名也不是每次都有用了。不管是通过AndroidStudio Run
还是通过assemble
进行打包后安装,都会时不时的出现Send app for a securitycheck
的提示。虽然比起Harmful app blocked
弹窗危害性没有那么大,但是也还是挺膈应人的。
我后来发现每次通过Build/Generate Signed Bundle or APK
打包后安装,则没有这个弹窗了。由于测试的设备仅有一个设备,这个瓜就不保真了!