Bootstrap

APK打包和签名

1、debug/release版本

  • Build/Make Project编译项目后,会默认生成一个app-debug.apk版本的APK,AS运行就是把这个文件通过adb install 方式安装到手机的

image.png

  • 我们可以选择使用release编译版本

image.png

  • 再次Build/Make Project编译项目后,就会出现release版本的APK

image.png

2、签名打包流程

2-1、生成签名文件

  • 第一步:Build -> Generate Signed Bundle / APL

image.png

  • 第二步:选择APK

image.png

  • 第三步:因为我们还没有签名文件,这里选择Create new…

image.png

  • 第四步:选择keystore保存的路径,填写keystore和key密码。ketystore密码和key密码在后面会用到。其他信息不是很重要,按实际情况写就好。
  • 主要有以下几个字段
    • keystore path:签名文件的文件路径
    • keystore password:密码,这里写的:android
    • key alias:别名,这里写的:key0
    • key password:密码,这里写的:android

image.png

  • 这里注意下这两个keystore password和key password要一模一样,不然会报错

image.png

  • 第五步:点击ok按钮。可以看到,重要的信息都显示在这里了,点击next。

image.png

  • 第六步:在Build Type类型选择release,点击Finish,release是发布版本用的签名文件,选择debug是debug用的签名文件。

image.png

  • 这样就会在刚刚选的路径下面生成一个签名文件:“C:\Users\chun3.wang\Desktop\test.jks”,格式是jks

2-2、配置签名文件

  • app/build.gradle添加以下配置
android {
    // 签名文件的声明
    signingConfigs {
        release {
            storeFile file('C:\\Users\\chun3.wang\\Desktop\\test.jks')
            storePassword 'android'
            keyAlias 'key0'
            keyPassword 'android'
        }
        debug {
            storeFile file('C:\\Users\\chun3.wang\\Desktop\\test.jks')
            storePassword 'android'
            keyAlias 'key0'
            keyPassword 'android'
        }
    }

    // 编译类型
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            // 表示release版本使用上述声明的签名文件 signingConfigs.release
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

            // 表示debug版本使用上述声明的签名文件
            signingConfig signingConfigs.debug
        }
    }
}
  • 再次Build/Make Project编译项目后,就会出现release版本的APK,并且是已经签名过的

image.png

  • 小结:就是为debug/release版本配置一个签名文件

2-3、APK签名打包

  • 上述方式生成的APK文件在build目录下,build/clean project之后就会被删除,这里再介绍一个生成签名APK的新方法

Build/Generate Bundle(s) / APK(s)
image.png
image.png
image.png
image.png

  • 最终就会在app/release或者app/debug下面生成APK文件

image.png

3、配置APK路径和名称

  • outputFileName:修改生成APK的名称
  • 这里实际没有改生成APK的路径,只是把app/release中的APK复制一份到新路径去app/apk/release中

image.png

android {

    android.applicationVariants.all { variant ->
        variant.outputs.all {


            // 最终输出的APK名称  Signer_1.0_release_202305150559.apk
            // rootProject.name 整个项目的名称
            // defaultConfig.versionName 这里是版本号
            // variant.buildType.name 这个是编译类型 release/debug
            def today = new Date()
            outputFileName = "${rootProject.name}_${defaultConfig.versionName}_${variant.buildType.name}_${today.format('yyyyMMddHHmm')}.apk"


            // 打包完成后,复制apk到指定文件夹,最终地址 Signer\app\apk\release\Signer_1.0_release_202305150602.apk
            variant.assemble.doLast {
                File out = new File("${project.projectDir.absolutePath}/apk/${variant.buildType.name}")
                copy {
                    variant.outputs.forEach { file ->
                        copy {
                            from file.outputFile
                            into out
                        }
                    }
                }
            }
        }
    }
}

4、其他签名方式

4-1、jarsigner签名

  • jarsigner是在JDK目录下,例如(D:\IT\Java\jdk1.8.0_231\bin)
  • 语法格式:jarsigner -verbose -keystore xxx.jks -signedjar xxx1.apk xxx2.apk xxx3
    • xxx.jks:为你的指纹证书路径及名字
    • xxx1.apk:为签名后的包要保存的路径及包名,后缀为.apk
    • xxx2.apk:为未签名的包的路径及包名,后缀为.apk
    • xxx3:为创建证书时的别名,上面创建时的Alias值或看这
jarsigner -verbose -keystore D:\AndroidStudioProjects\platom_signs\platform_EF1E.jks -signedjar D:\项目文档\V51DK\XCMascotUI111.apk D:\项目文档\V51DK\XCMascotUI.apk platform
输入密钥库的密码短语:
   正在添加: META-INF/MANIFEST.MF
   正在添加: META-INF/PLATFORM.SF
   正在添加: META-INF/PLATFORM.RSA
  正在签名: META-INF/androidx.customview_customview.version
  正在签名: META-INF/kotlin-android-extensions-runtime.kotlin_module
  正在签名: res/drawable/bg_launcher_push_content.9.png
  正在签名: res/drawable-mdpi-v4/abc_ic_star_half_black_16dp.png
  正在签名: assets/listen_up.pag
  正在签名: res/drawable-hdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png
  正在签名: res/drawable-mdpi-v4/icon_user_avatar_def.png
  正在签名: res/drawable-xxhdpi-v4/abc_text_select_handle_right_mtrl_dark.png
  正在签名: res/drawable-xxhdpi-v4/abc_btn_radio_to_on_mtrl_015.png
...

>>> 签名者
    X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=EcarX, L=DaLian, ST=LiaoNing, C=CN
    Signature algorithm: SHA256withRSA, 2048 位密钥
    [可信证书]

jar 已签名。

警告:
签名者证书为自签名证书。

4-2、使用APKSign签名

  • 软件下载地址:APKSign.rar
  • 操作步骤:https://www.ijiami.cn/help.html

image.pngimage.png

  • 填写信息分别为
    • APK:刚刚下载的加固但没有签名的APK文件
    • 位置:签名文件jks的位置(Android Studio生成的签名文件)
    • 密码:对应storePassword
    • 别名:对应keyAlias(一般自动生成)
    • 密码:对应keyPassword
    • 签名后位置:一般与之前APK同目录
  • 对照Studio build.gradle(app)中的签名信息,填入APKSign中,签名成功后得到加固并且签名的APK

4-3、清除签名

  • 解压APK之后的目录

image.png

  • 其中META-INF里面的文件如下

image.png

  • 清楚APK签名的方法:解压APK文件,找到并删除META-INF文件夹,再重新压缩即可

image.png

4、keytool

  • keytool命令位于JDK中,Java\jdk-19\bin
  • Android Studio中也有:\Android Studio\jre\bin\keytool.exe

4-1、获取签名文件的SHA1

  • android应用默认的签名文件在:C:\Users\chun3.wang.android\debug.keystore,默认的密钥库口令:android
  • 注意Android debug默认的签名文件格式是.keystore,上面我们生成的签名文件是.jks
  • 用下述命令就可以得到debug.keystore的SHA1,中间要输入密钥库口令storePassword,这里就是android
D:\IT\Android Studio\jre\bin>keytool -list -v -keystore "C:\Users\chun3.wang\.android\debug.keystore"
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: androiddebugkey
创建日期: 2023年3月22日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=US, O=Android, CN=Android Debug
发布者: C=US, O=Android, CN=Android Debug
序列号: 1
生效时间: Wed Mar 22 14:17:06 CST 2023, 失效时间: Fri Mar 14 14:17:06 CST 2053
证书指纹:
         SHA1: D5:AF:C9:F6:42:48:A9:A8:1D:8E:07:B6:7D:79:01:20:3D:07:06:67
         SHA256: 6E:A2:74:F9:85:74:D3:5F:1A:8B:99:79:38:AF:40:02:C3:E3:4A:6C:2D:74:B3:A7:AC:11:9F:D7:70:2C:AE:6E
签名算法名称: SHA1withRSA (弱)
主体公共密钥算法: 2048 位 RSA 密钥
版本: 1
  • 再看看我们刚刚生成的签名文件
D:\IT\Java\jdk-19\bin>keytool -list -v -keystore "C:\Users\chun3.wang\.android\debug.keystore"
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: androiddebugkey
创建日期: 2023322日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=US, O=Android, CN=Android Debug
发布者: C=US, O=Android, CN=Android Debug
序列号: 1
生效时间: Wed Mar 22 14:17:06 CST 2023, 失效时间: Fri Mar 14 14:17:06 CST 2053
证书指纹:
         SHA1: D5:AF:C9:F6:42:48:A9:A8:1D:8E:07:B6:7D:79:01:20:3D:07:06:67
         SHA256: 6E:A2:74:F9:85:74:D3:5F:1A:8B:99:79:38:AF:40:02:C3:E3:4A:6C:2D:74:B3:A7:AC:11:9F:D7:70:2C:AE:6E
签名算法名称: SHA1withRSA ()
主体公共密钥算法: 2048 位 RSA 密钥
版本: 1


*******************************************
*******************************************



Warning:
<androiddebugkey> 使用的 SHA1withRSA 签名算法被视为存在安全风险。此算法将在未来的更新中被禁用。

D:\IT\Java\jdk-19\bin>keytool -list -v -keystore "C:\Users\chun3.wang\Desktop\test.jks"
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: key0
创建日期: 2023515日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=arthur
发布者: CN=arthur
序列号: 6748bcf0
生效时间: Mon May 15 17:13:30 CST 2023, 失效时间: Fri May 08 17:13:30 CST 2048
证书指纹:
         SHA1: 71:06:F0:08:B7:B6:B8:54:FA:77:E4:8E:2B:51:86:B1:B2:9F:CF:56
         SHA256: C0:BB:4C:13:1E:18:A1:DF:FC:1A:E8:29:11:4C:E2:DC:7E:26:54:BD:F0:D0:4C:A6:73:5E:38:2A:72:5F:BF:24
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 67 6F ED 58 A5 97 F3 D9   67 17 E7 E6 8C 76 02 22  go.X....g....v."
0010: 4A EB B2 6B                                        J..k
]
]



*******************************************
*******************************************
  • 有时候上述命令会报错Invalid keystore format,这是由于keystore是用和当前jdk的不同版本生成的,
C:\Users\chun3.wang>keytool -list -v -keystore "C:\Users\chun3.wang\.android\debug.keystore"
输入密钥库口令:
keytool 错误: java.io.IOException: Invalid keystore format
java.io.IOException: Invalid keystore format
        at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:663)
        at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
        at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
        at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
        at java.security.KeyStore.load(KeyStore.java:1445)
        at sun.security.tools.keytool.Main.doCommands(Main.java:926)
        at sun.security.tools.keytool.Main.run(Main.java:366)
        at sun.security.tools.keytool.Main.main(Main.java:359)

5、debug默认签名

  • 没有签名的apk是不可以装在手机上的
  • Android Studio新建一个项目后,可以直接运行把APK安装到手机,我们是没有进行任何签名操作的,为何app-debug.apk能安装到手机上。因为这里使用的是默认Android签名文件,android应用默认的签名文件在:C:\Users\chun3.wang.android\debug.keystore
  • debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;Debug模式下签名用的证书自从它创建之日起,1年后就会失效。
  • debug.keystore在不同的机器上所生成的可能都不一样,就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种程序不能覆盖安装的问题,相当于软件不具备升级功能
  • 断点调试只能在debug版本上使用,release版本无法使用
默认debug.keystore的信息如下:
Keystore name: “debug.keystore”
Keystore password: “android”
Key alias: “androiddebugkey”
Key password: “android”
CN: “CN=Android Debug,O=Android,C=US”

5-1、没有签名

  • 如果一个渠道包没有签名的话,Android Studio会直接报错,无法运行,侧面也验证了没有签名是不能安装到手机上的

Error: The apk for your currently selected variant cannot be signed. Please specify a signing configuration for this variant (release).
image.png

6、keystore和jks区别

keystore 是Eclipse打包生成的签名,jks是Android studio 生成的签名!都是用来打包的,并保证应用的唯一性
很多第三方市场,我们上传apk的时候,他们只支持keystore,所以我们需要转换

jks转p12转keystore

  • jks转p12

keytool -importkeystore -srckeystore /your-path/demo.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore /your-path/client.p12
-importkeystore 从其他密钥库导入一个或所有条目
-srckeystore 源密钥库名称
/your-path/demo.jks jks文件所在位置
-srcstoretype 源密钥库类型
-deststoretype 目标密钥库类型
-destkeystore 目标密钥库名称
/your-path/client.p12 生成的pkcs12文件所在位置

  • p12转keystore

keytool -importkeystore -srckeystore /your-path/client.p12 -srcstoretype PKCS12 -destkeystore /your- path/demo.keystore -deststoretype JKS
/your-path/client.p12 pkcs12文件所在位置
/your-path/demo.keystore 生成的keystore文件所在位置

D:\IT\Java\jdk-19\bin>keytool -importkeystore -srckeystore "C:\Users\chun3.wang\Desktop\test.jks" -srcstoretype JKS -deststoretype PKCS12 -destkeystore "C:\Users\chun3.wang\Desktop\test.p12"
正在将密钥库 C:\Users\chun3.wang\Desktop\test.jks 导入到 C:\Users\chun3.wang\Desktop\test.p12...
输入目标密钥库口令:
再次输入新口令:
输入源密钥库口令:
已成功导入别名 key0 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消

D:\IT\Java\jdk-19\bin>keytool -importkeystore -srckeystore "C:\Users\chun3.wang\Desktop\test.p12" -srcstoretype PKCS12 -destkeystore "C:\Users\chun3.wang\Desktop\test.keystore" -deststoretype JKS
正在将密钥库 C:\Users\chun3.wang\Desktop\test.p12 导入到 C:\Users\chun3.wang\Desktop\test.keystore...
输入目标密钥库口令:
再次输入新口令:
输入源密钥库口令:
已成功导入别名 key0 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消

Warning:
JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore C:\Users\chun3.wang\Desktop\test.keystore -destkeystore C:\Users\chun3.wang\Desktop\test.keystore -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。

keystore转jks

D:\IT\Java\jdk-19\bin>keytool -v -importkeystore -srcstoretype PKCS12 -srckeystore "C:\Users\chun3.wang\Desktop\test.keystore" -deststoretype JKS -destkeystore "C:\Users\chun3.wang\Desktop\out.jks"
正在将密钥库 C:\Users\chun3.wang\Desktop\test.keystore 导入到 C:\Users\chun3.wang\Desktop\out.jks...
输入目标密钥库口令:
再次输入新口令:
输入源密钥库口令:
已成功导入别名 key0 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
[正在存储C:\Users\chun3.wang\Desktop\out.jks]

Warning:
JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore C:\Users\chun3.wang\Desktop\out.jks -destkeystore C:\Users\chun3.wang\Desktop\out.jks -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。

7、AAB vs APK

签名打包生成的文件是xx.apk,但是也会有xx.aab格式的。
AAB(Android App Bundle)支持模块化,结合Google Play的动态支付(Dynamic Delivery)功能,将一个apk文件差分成多个apk,按照需要加载内容(包括加载C/C++ libraries),这样开发者可以随时按照需要交付功能,而不是仅限在安装过程中。谷歌宣布谷歌应用商店上新的应用必须使用AAB格式文件之后。
APK(Android application package)需要将所有内容打包成为一个被Android系统所能识别的文件,才可以被运行,一个apk文件内包含被编译的代码文件(.dex 文件),文件资源(resources), 原生资源文件(assets),证书(certificates),和清单文件(manifest file)。
AAB格式文件无法像apk文件一样直接安装,需要生成完整apk或者split apks并签名才可以安装。优点是不再需要一个apk来包含所有类型的安卓设备的所有内容,开发者只需要根据需求上传更新,减少了应用程序安装包的大小体积。

7-1、生成aab文件

image.png
image.png
image.png

待研究问题

key可以有多个???

;