Android 开发工程师的必备技能。
如果刚开始没有签名,可以通过命令行的方式来生成签名:keytool -genkey -alias ifeegoo -keyalg RSA -validity 100 -keystore ifeegoo.keystore。
ifeegoo@ifeegoo % keytool -genkey -alias ifeegoo -keyalg RSA -validity 100 -keystore ifeegoo.keystore Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: ifeegoo What is the name of your organizational unit? [Unknown]: ifeegoo What is the name of your organization? [Unknown]: ifeegoo What is the name of your City or Locality? [Unknown]: Shenzhen What is the name of your State or Province? [Unknown]: Guangdong What is the two-letter country code for this unit? [Unknown]: 86 Is CN=ifeegoo, OU=ifeegoo, O=ifeegoo, L=Shenzhen, ST=Guangdong, C=86 correct? [no]: yes Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 100 days for: CN=ifeegoo, OU=ifeegoo, O=ifeegoo, L=Shenzhen, ST=Guangdong, C=86 ifeegoo@ifeegoo %
当然我们也可以通过 Android Studio 自带的签名生成工具:Android Studio -> Build -> Generate Signed Bundle or APK -> APK -> Key store path ->
Create new。通过这种方式生成签名文件,有的 Android Studio 版本会有一个错误提醒,导致无法正常生成签名文件:
Error Key was created with errors: Warning: JKS 秘钥库使用专用格式。建议使用”keytool -importkeystore -srckeystore *** -destkeystore *** -deststoretype pkcs12″迁移到行业标准格式 PKCS12。
但是有些版本 Android Studio 不会提醒,针对不提醒的生成 keystore 文件,我们可以通过以下命令来查看 keystore 的相关信息:keytool -list -v -keystore 签名文件路径 -storepass 密码
ifeegoo@ifeegoo ~ % keytool -list -v -keystore /Users/ifeegoo/Desktop/test.keystore -storepass test Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry Alias name: test Creation date: Jul 31, 2020 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=test, OU=test, O=test, L=Shenzhen, ST=Guangdong, C=86 Issuer: CN=test, OU=test, O=test, L=Shenzhen, ST=Guangdong, C=86 Serial number: 4b533e71 Valid from: Fri Jul 31 12:56:22 CST 2020 until: Sun Jul 07 12:56:22 CST 2120 Certificate fingerprints: SHA1: **** SHA256: **** Signature algorithm name: SHA256withRSA Subject Public Key Algorithm: 2048-bit RSA key Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: F1 AB E7 ** 25 31 CB 6A AB 74 DC 22 36 E1 A8 EE ....%1.j.t.26... 0010: 94 ** 5D 3C .\]< ] ] ******************************************* ******************************************* Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore /Users/ifeegoo/Desktop/test.keystore -destkeystore /Users/ifeegoo/Desktop/test.keystore -deststoretype pkcs12".
很明显,我们可以看到 Keystore type 是 JKS,同时最后一段警告提醒,建议转到 PKCS12 格式,然后告知你了相关的命令:”keytool -importkeystore -srckeystore /Users/ifeegoo/Desktop/test.keystore -destkeystore /Users/ifeegoo/Desktop/test.keystore -deststoretype pkcs12″,我们通过这个命令处理下 test.keystore:
ifeegoo@ifeegoo ~ % keytool -list -v -keystore /Users/ifeegoo/Desktop/test.keystore -storepass test Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 1 entry Alias name: cutecatos Creation date: Jul 31, 2020 Entry type: PrivateKeyEntry ****** ******
从以上内容,我们就可以看出现在的 keystore 类型已经变成了 PKCS12 了,并且没有警告提醒了。
首先我们来看一下,如果你没有合成适合 Android Studio 调试的签名,那就只能打一个未签名的包 unsigned.apk,然后通过以下命令行来进行系统签名:
java -jar signapk.jar platform.x509.pem platform.pk8 unsigned.apk signed.apk
请注意:自己在网上找下 signapk.jar 这个 jar 包,同时你的电脑上已经安装好了 Java SDK 环境。
当然我们最好是能够生成让 Android Studio 进行调试的包含系统签名的签名文件。接下来我们通过以下几个步骤:
1.把 pkcs8 格式的私钥转化成 pkcs12 格式:
注意:如果 .pk8 和 .x509.pem 文件有密码的话,那就不要带上 -nocrypt 标记,然后命令执行后,会让你输入密码!
openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt
2.把 x509.pem 公钥转换成 pkcs12 格式:
openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name platform
3.生成 platform.keystore:
keytool -importkeystore -deststorepass platform -destkeypass platform -destkeystore platform.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass platform -alias platform
以上步骤就能够生成可用于 Android Studio 直接调试的包含系统 platform 证书的签名文件!
我们先通过以上方法分别生成 platform.keystore/share.keystore/media.keystore/testkey.keystore/verity.keystore 文件:
// platform.pk8 openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name platform keytool -importkeystore -deststorepass platform -destkeypass platform -destkeystore platform.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass platform -alias platform // media.pk8 注意密码最低为六位,所以里面设置密码的时候设置了成了 imedia,如果能和 alias 保持一致的话,最好保持一致,便于记忆 openssl pkcs8 -in media.pk8 -inform DER -outform PEM -out media.priv.pem -nocrypt openssl pkcs12 -export -in media.x509.pem -inkey media.priv.pem -out media.pk12 -name media keytool -importkeystore -deststorepass imedia -destkeypass imedia -destkeystore media.keystore -srckeystore media.pk12 -srcstoretype PKCS12 -srcstorepass imedia -alias media // shared.pk8 openssl pkcs8 -in shared.pk8 -inform DER -outform PEM -out shared.priv.pem -nocrypt openssl pkcs12 -export -in shared.x509.pem -inkey shared.priv.pem -out shared.pk12 -name shared keytool -importkeystore -deststorepass shared -destkeypass shared -destkeystore shared.keystore -srckeystore shared.pk12 -srcstoretype PKCS12 -srcstorepass shared -alias shared // testkey.pk8 openssl pkcs8 -in testkey.pk8 -inform DER -outform PEM -out testkey.priv.pem -nocrypt openssl pkcs12 -export -in testkey.x509.pem -inkey testkey.priv.pem -out testkey.pk12 -name testkey keytool -importkeystore -deststorepass testkey -destkeypass testkey -destkeystore testkey.keystore -srckeystore testkey.pk12 -srcstoretype PKCS12 -srcstorepass testkey -alias testkey // verity.pk8 openssl pkcs8 -in verity.pk8 -inform DER -outform PEM -out verity.priv.pem -nocrypt openssl pkcs12 -export -in verity.x509.pem -inkey verity.priv.pem -out verity.pk12 -name verity keytool -importkeystore -deststorepass verity -destkeypass verity -destkeystore verity.keystore -srckeystore verity.pk12 -srcstoretype PKCS12 -srcstorepass verity -alias verity
我们下来可以将以上几个 keystore 全部整合到同一个 keystore 文件中了,为了整合以上 platform.keystore/share.keystore/media.keystore/testkey.keystore/verity.keystore 到同一个文件,想要将这个文件命名成 Android.keystore,然后密码也是 Android,但是里面的 alias 还是各个 platform/share 等,我们就用以下命令来生成包含 platform 签名的 Android.keystore 文件。我们就先用以下命令生成一个包含 platform 签名信息的基准文件 Android.keystore。因为我这边可能有多个 ROM 对应不同一套签名,所以后面追加了标识符:02050101
openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name platform-02050101 keytool -importkeystore -deststorepass Android -destkeypass Android -destkeystore Android.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass Android -alias platform-02050101
然后我们用以上方式生成其他的 share.keystore/media.keystore/testkey.keystore/verity.keystore 文件,我们在合并这些签名文件之前,先用命令行来确认下刚才生成的 Android.keystore 文件状态:
ifeegoo@ifeegoo blog % keytool -list -v -keystore Android.keystore -storepass Android Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 1 entry Alias name: platform-02050101 Creation date: Aug 6, 2020 Entry type: PrivateKeyEntry
我们可以看到目前里面只有一个 Entry,文件名称和密码,还有对应的 Alias 也是我们想要的,然后 Keystore 类型也是 PKCS12。其他几个系统签名我们也通过标识符区分来生成:
// media.pk8 注意密码最低为六位,所以里面设置密码的时候设置了成了 imedia,如果能和 alias 保持一致的话,最好保持一致,便于记忆 openssl pkcs8 -in media.pk8 -inform DER -outform PEM -out media.priv.pem -nocrypt openssl pkcs12 -export -in media.x509.pem -inkey media.priv.pem -out media.pk12 -name media-02050101 keytool -importkeystore -deststorepass imedia -destkeypass imedia -destkeystore media.keystore -srckeystore media.pk12 -srcstoretype PKCS12 -srcstorepass imedia -alias media-02050101 // shared.pk8 openssl pkcs8 -in shared.pk8 -inform DER -outform PEM -out shared.priv.pem -nocrypt openssl pkcs12 -export -in shared.x509.pem -inkey shared.priv.pem -out shared.pk12 -name shared-02050101 keytool -importkeystore -deststorepass shared -destkeypass shared -destkeystore shared.keystore -srckeystore shared.pk12 -srcstoretype PKCS12 -srcstorepass shared -alias shared-02050101 // testkey.pk8 openssl pkcs8 -in testkey.pk8 -inform DER -outform PEM -out testkey.priv.pem -nocrypt openssl pkcs12 -export -in testkey.x509.pem -inkey testkey.priv.pem -out testkey.pk12 -name testkey-02050101 keytool -importkeystore -deststorepass testkey -destkeypass testkey -destkeystore testkey.keystore -srckeystore testkey.pk12 -srcstoretype PKCS12 -srcstorepass testkey -alias testkey-02050101 // verity.pk8 openssl pkcs8 -in verity.pk8 -inform DER -outform PEM -out verity.priv.pem -nocrypt openssl pkcs12 -export -in verity.x509.pem -inkey verity.priv.pem -out verity.pk12 -name verity-02050101 keytool -importkeystore -deststorepass verity -destkeypass verity -destkeystore verity.keystore -srckeystore verity.pk12 -srcstoretype PKCS12 -srcstorepass verity -alias verity-02050101
我们按照上面的命令来生成:share.keystore/media.keystore/testkey.keystore/verity.keystore 几个文件,最后通过以下命令来整合到 Android.keystore 里面去:
keytool -importkeystore -srckeystore media.keystore -destkeystore Android.keystore -srcalias media-02050101 -destalias media-02050101 -srcstorepass imedia -deststorepass Android keytool -importkeystore -srckeystore shared.keystore -destkeystore Android.keystore -srcalias shared-02050101 -destalias shared-02050101 -srcstorepass shared -deststorepass Android keytool -importkeystore -srckeystore testkey.keystore -destkeystore Android.keystore -srcalias testkey-02050101 -destalias testkey-02050101 -srcstorepass testkey -deststorepass Android keytool -importkeystore -srckeystore verity.keystore -destkeystore Android.keystore -srcalias verity-02050101 -destalias verity-02050101 -srcstorepass verity -deststorepass Android
最后我们可以通过 Android Studio 的可视化工具来检验 Android.keystore 密码是否正确,然后其他各种证书信息是否集成:
我们也可以通过命令行来查看是否被整合:
ifeegoo@ifeegoo final % keytool -list -v -keystore Android.keystore -storepass Android Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 5 entries **************
到此系统签名的整合与合并就大功告成了!
参考文档:https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html
上一篇: « 使用 TestFlight 进行 iOS App 内测 下一篇: 推荐的移动应用的版本名称管理规范 »