一、V1和V2签名介绍

1.工具介绍

jarsigner是JDK提供的针对jar包签名的通用工具, 位于JDK/bin/jarsigner.exe

apksigner是Google官方提供的针对Android apk签名及验证的专用工具, 位于Android SDK/build-tools/SDK版本/apksigner.bat

不管是apk包,还是jar包,本质都是zip格式的压缩包,所以它们的签名过程都差不多(仅限V1签名), 以上两个工具都可以对Android apk包进行签名.

2.V1和V2签名的区别

从Android 7.0开始, 谷歌增加新签名方案 V2 Scheme (APK Signature);

但Android 7.0以下版本, 只能用旧签名方案 V1 scheme (JAR signing)

V1签名:

来自JDK(jarsigner), 对zip压缩包的每个文件进行验证, 签名后还能对压缩包修改(移动/重新压缩文件) 对V1签名的apk/jar解压,在META-INF存放签名文件(MANIFEST.MF, CERT.SF, CERT.RSA), 其中MANIFEST.MF文件保存所有文件的SHA1指纹(除了META-INF文件), 由此可知: V1签名是对压缩包中单个文件签名验证

V2签名:

来自Google(apksigner), 对zip压缩包的整个文件验证, 签名后不能修改压缩包(包括zipalign), 对V2签名的apk解压,没有发现签名文件,重新压缩后V2签名就失效, 由此可知: V2签名是对整个APK签名验证

V2签名优点很明显:
签名更安全(不能修改压缩包)
签名验证时间更短(不需要解压验证),因而安装速度加快

注意: apksigner工具默认同时使用V1和V2签名,以兼容Android 7.0以下版本


3.zipalign和V2签名

位于Android SDK/build-tools/SDK版本/zipalign.exe

zipalign 是对zip包对齐的工具,使APK包内未压缩的数据有序排列对齐,从而减少APP运行时内存消耗

zipalign -v 4 in.apk out.apk   //4字节对齐优化

zipalign -c -v 4 in.apk    //检查APK是否对齐

zipalign可以在V1签名后执行 但zipalign不能在V2签名后执行,只能在V2签名之前执行!!!

二、生成签名(Android.keystore)

cmd进入JDK的bin目录,运行如下命令:

keytool -genkeypair -keystore 密钥库名 -alias 密钥别名 -validity 天数 -keyalg RSA

keytool -genkey -alias android.keystore -keyalg RSA -validity 20000 -keystore android.keystore

(-validity 30000代表有效期天数),命令完成后,bin目录中会生成android.keystore

参数:

-genkeypair 生成一条密钥对(由私钥和公钥组成)

-keystore 密钥库名字以及存储位置(默认当前目录)

-alias 密钥对的别名(密钥库可以存在多个密钥对,用于区分不同密钥对)

-validity 密钥对的有效期(单位: 天)

-keyalg 生成密钥对的算法(常用RSA/DSA,DSA只用于签名,默认采用DSA)

-delete 删除一条密钥

D:\SafetyTest\AndroidSDK\jdk-16.0.2\bin
λ keytool -genkeypair -keystore debug.keystore -alias debug -validity 30000 -keyalg RSA
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: ZG
您的组织单位名称是什么?
[Unknown]: Debug
您的组织名称是什么?
[Unknown]: Debug
您所在的城市或区域名称是什么?
[Unknown]: SZ
您所在的省/市/自治区名称是什么?
[Unknown]: SZ
该单位的双字母国家/地区代码是什么?
[Unknown]: CN
CN=ZG, OU=Debug, O=Debug, L=SZ, ST=SZ, C=CN是否正确?
[否]: Y

正在为以下对象生成 2,048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 30,000 天):
CN=ZG, OU=Debug, O=Debug, L=SZ, ST=SZ, C=CN

提示: 可重复使用此条命令,在同一密钥库中创建多条密钥对

例如: 在debug.keystore中新增一对密钥,别名是debug

keytool -genkeypair -keystore debug.keystore -alias debug -validity 30000

为apk增加签名:

jarsigner -digestalg SHA1 -sigalg MD5withRSA -tsa -verbose -keystore debug.keystore -signedjar coolapk-signed.apk coolapk.apk debug

如果不带-digestalg SHA1 -sigalg MD5withRSA签名后的apk安装也会不成功,INSTALL_PARSE_FAILED_NO_CERTIFICATES的错误,如果不带-tsa会报一个时间方面的警告.


对于 Android Studio 生成的 .jks 证书文件

jarsigner -digestalg SHA1 -sigalg SHA1withRSA(或SHA1withDSA) -verbose -keystore xxx.jks -signedjar xxx.apk(签名后的apk名字) xxx.apk(需要签名的apk) xxx(keystore别名)

例如:​jarsigner -digestalg SHA1 -sigalg SHA1withRSA -verbose -keystore debug.jks -signedjar sign.apk dest.apk

如何查看密钥库呢?

看命令

keytool -list -v -keystore android.keystore   输入你设置的keystore密码即可

例如: keytool -list -v -keystore debug.keystore

ps:(证书路径使用绝对路径)

#keytool -list -v -keystore D:\AndroidSDK\jdk-16.0.2\keys.jks
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN
您的密钥库包含 1 个条目

别名: key
创建日期: 2022年1月22日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=Debug, OU=Test, O=Test, L=SZ, ST=GD, C=CN
发布者: CN=Debug, OU=Test, O=Test, L=SZ, ST=GD, C=CN
序列号: 69930b94
生效时间: Sat Jan 22 21:43:42 CST 2022, 失效时间: Wed Jan 16 21:43:42 CST 2047
证书指纹:
SHA1: FA:F9:94:16:F7:9A:72:2C:06:0A:0F:D3:56:61:06:8A:02:B2:B4:54
SHA256: 2A:F1:45:D5:D1:33:95:F0:B8:5D:AE:FA:60:48:5A:1E:8C:80:7F:A4:C9:DE:CA:86:7B:9D:B0:00:D9:66:34:67
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3

三、签名使用

1、v1、v2签名方式选择查看所需信息,参数说明如下:

App打包时v1和v2签名可在Build/Generate Signed APK选项下手动勾选(已生成jks文件),也可在build.gradle进行配置v1SigningEnabledv2SigningEnabled,示例如下

signingConfigs {
release {
keyAlias 'test'
keyPassword 'test'
storeFile file('./keystore/test.jks')
storePassword 'test'
v1SigningEnabled true
v2SigningEnabled true
}
debug {
keyAlias 'test'
keyPassword 'test'
storeFile file('./keystore/test.jks')
storePassword 'test'
v1SigningEnabled true
v2SigningEnabled true
}
}

2、使用jarsigner进行v1签名

签名命令​​:

jarsigner -verbose -keystore D:\xxx.jks(签名文件路径) -signedjar xxx.apk(签名后的apk名字) xxx.apk(需要签名的apk) xxx(jks证书别名)

签名示例​​:

jarsigner -verbose -keystore D:\jdk-16.0.2\Testkey.jks -signedjar test.apk D:\jdk-16.0.2\bin\hema.apk Key0

1. #删除签名
call aapt remove -v com.huawei.intelligenttv META-INF/MANIFEST.MF META-INF/CERT.SF META-INF/CERT.RSA

2. #重新签名
call jarsigner -verbose -keystore android.keystore -signedjar test_signer.apk D:\SafetyTest\jdk-16.0.2\com.huawei.intelligenttv android.keystore (#apk路径使用绝对路径)

3. #校验签名
call jarsigner -verbose -certs -verfy test_signer.app
call adb install -r test_signer.app



3、使用apksigner进行v1/v2签名

从​​官网关于apksigner的介绍​​​来看,签名前需使用​​zipalign​​对齐工具进行包对其,引用官网警告

警告:如果您在使用 apksigner 为 APK 签名后对 APK 进行进一步更改,则 APK 的签名将会失效。因此,在为 APK 签名之前,您必须使用 zipalign 等工具。

对齐命令​​:​​zipalign -v 4 infile.apk outfile.apk​

说明:对齐 infile.apk 并将其保存为 outfile.apk

对齐验证​​:​​zipalign -c -v 4 existing.apk​

说明:确认 existing.apk 的对齐方式

签名命令​:

apksigner sign --ks 密钥库名 --ks-key-alias 密钥别名 --out 签名后apk 需要签名的apk

签名示例:

apksigner sign --ks D:\test.jks --ks-key-alias test --out sign.apk D:\zipalign.apk

ps:若密钥库中有多个密钥对,则必须指定密钥别名

禁用V2签名

apksigner sign --v2-signing-enabled false --ks 密钥库名 xxx.apk

参数:

   --ks-key-alias       密钥别名,若密钥库有一个密钥对,则可省略,反之必选

   --v1-signing-enabled 是否开启V1签名,默认开启

   --v2-signing-enabled 是否开启V2签名,默认开启

例如:

在debug.keystore密钥库只有一个密钥对
apksigner sign --ks debug.keystore MyApp.apk

在debug.keystore密钥库中有多个密钥对,所以必须指定密钥别名
apksigner sign --ks debug.keystore --ks-key-alias debugkey MyApp.apk


完整示例

zipalign -v 4 test.apk zipalign.apk     //对齐
zipalign -c -v 4 zipalign.apk //对齐验证
apksigner sign --ks test.jks --ks-key-alias test --out sign.apk zipalign.apk //签名
apksigner verify -v sign.apk // 签名验证


四、签名验证

使用apksigner验证Apk签名是否成功

1.方法一(keytool,只支持V1签名校验)

进入JDK/bin, 输入命令
keytool -printcert -jarfile MyApp.apk (显示签名证书信息)

2.方法二(apksigner,支持V1和V2签名校验)

进入  Android SDK/build-tools/SDK版本, 输入命令
apksigner verify -v --print-certs xxx.apk
其中,apksigner.jar位于C:\Android_SDK\build-tools\25.0.2\lib目录下

参数:
-v, --verbose 显示详情(显示是否使用V1和V2签名)
--print-certs 显示签名证书信息

示例如下(成功与未签名)

➜  D:\Android\sdk\build-tools\27.0.3
➜ # apksigner.bat verify -v /Desktop/demo.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Number of signers: 1
java -jar apksigner.jar verify -v my.apk
--
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true

五、查看apk签名

1、查看keystore证书文件内容,请运行以下命令:keytool -list -v -keystore [enter keystore name] -storepass [enter keystore password]

$ keytool -list -v -keystore my_keystore -storepass 123456
$密钥库类型: JKS
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: zr
创建日期: 2014-10-14
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=zeng run, L=Beijing
发布者: CN=zeng run, L=Beijing
序列号: 58ec916d
有效期开始日期: Tue Oct 14 16:19:26 CST 2014, 截止日期: Sat Oct 08 16:19:26 CST 2039
证书指纹:
MD5: C4:73:2F:59:F5:CA:76:C1:10:59:98:E8:F9:23:9E:9E
SHA1: 16:90:E7:D3:E8:ED:9D:E0:5E:47:9A:3B:D4:D4:8E:D0:40:AF:BD:23
SHA256: FF:0F:AF:A5:FA:8F:A8:25:8D:8D:E7:17:08:71:46:CD:60:F1:44:F0:88:81:6F:3E:7B:61:AC:8F:B0:7D:17:CC
签名算法名称: SHA256withRSA
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E6 61 76 EB C6 99 7D 4B F6 B5 75 AD E1 FA 63 E5 .av....K..u...c.
0010: 3C D4 BC 5F <.._
]
]

2、要查看apk签名信息及证书内容,即CERT.RSA文件,可用以下命令:keytool -printcert -file /*/CERT.RSA

$ keytool -printcert -file /home/zr/CERT.RSA
所有者: CN=zeng run, L=Beijing
发布者: CN=zeng run, L=Beijing
序列号: 58ec916d
有效期开始日期: Tue Oct 14 16:19:26 CST 2014, 截止日期: Sat Oct 08 16:19:26 CST 2039
证书指纹:
MD5: C4:73:2F:59:F5:CA:76:C1:10:59:98:E8:F9:23:9E:9E
SHA1: 16:90:E7:D3:E8:ED:9D:E0:5E:47:9A:3B:D4:D4:8E:D0:40:AF:BD:23
SHA256: FF:0F:AF:A5:FA:8F:A8:25:8D:8D:E7:17:08:71:46:CD:60:F1:44:F0:88:81:6F:3E:7B:61:AC:8F:B0:7D:17:CC
签名算法名称: SHA256withRSA
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E6 61 76 EB C6 99 7D 4B F6 B5 75 AD E1 FA 63 E5 .av....K..u...c.
0010: 3C D4 BC 5F <.._
]
]


CSDN博客: ​http://blog.csdn.net/qq_32115439/article/details/55520012​