你是否错误地使用了调试密钥进行签名?
Google Play不允许您发布使用调试密钥库签名的应用程序。如果您尝试上传这样的APK,Google Play将会提示“您上传的APK是在调试模式下签名的。您需要以发布模式签署您的APK。”
但是,如果您尝试上传一个使用调试密钥库签名的更新,您将不会看到此消息;Google Play将显示与SHA1指纹相关的问题中显示的消息。
因此,首先请检查是否错误地使用了调试密钥来签署应用。
如何检查所使用的签名密钥?
从APK中获取信息
您可以使用Java keytool
命令来检查原始APK和更新APK使用的证书:
keytool -printcert -jarfile original.apk
keytool -printcert -jarfile update.apk
这将向您显示有关APK签名方式的详细信息,例如:
Owner: CN=My App, O=My Company, L=Somewhere, C=DE
Issuer: CN=My App, O=My Company, L=Somewhere, C=DE
Serial number: 4790b086
Valid from: Mon Nov 11 15:01:28 GMT 2013 until: Fri Mar 29 16:01:28 BST 2041
Certificate fingerprints:
MD5: A3:2E:67:AF:74:3A:BD:DD:A2:A9:0D:CA:6C:D4:AF:20
SHA1: A6:E7:CE:64:17:45:0F:B4:C7:FC:76:43:90:04:DC:A7:84:EF:33:E9
SHA256: FB:6C:59:9E:B4:58:E3:62:AD:81:42:...:09:FC:BC:FE:E7:40:53:C3:D8:14:4F
Signature algorithm name: SHA256withRSA
Version: 3
需要注意的重要部分 - 每个APK的 SHA1 指纹值、Owner 身份值以及 Valid from/until 日期。
如果 keytool
命令无法工作(-jarfile
选项需要 Java 7),您可以通过 jarsigner
命令获取更基本的信息:
jarsigner -verify -verbose:summary -certs original.apk
jarsigner -verify -verbose:summary -certs update.apk
很遗憾,这里并不显示SHA1指纹,但是会展示X.509所有者身份和证书到期日期。例如:
sm 4642892 Thu Apr 17 10:57:44 CEST 2014 classes.dex (and 412 more)
X.509, CN=My App, O=My Company, L=Somewhere, C=DE
[certificate is valid from 11/11/13 12:12 to 29/03/41 12:12]
[CertPath not validated: Path does not chain with any of the trust anchors]
在这种情况下,您可以忽略任何关于“CertPath未经验证”的消息,以及有关证书链或时间戳的警告。
比较APK之间的所有者、SHA1和到期值
如果所有者/X.509身份值为CN=Android Debug, O=Android, C=US
,则您使用了调试密钥而不是原始发布密钥签署APK
如果原始APK和更新APK之间的SHA1指纹值不同,则表示您没有同时为两个APK使用相同的签名密钥
如果两个APK之间的所有者/X.509身份值不同,或证书过期日期不同,则表示您没有同时为两个APK使用相同的签名密钥
请注意,即使两个证书之间的所有者/X.509值相同,这也并不意味着证书相同 - 如果其他任何内容不匹配 - 例如指纹值 - 则证书不同。
搜索原始密钥库,检查备份
如果两个APK具有不同的证书信息,则您必须找到原始密钥库,即具有Google Play(或keytool
)告诉您的第一个SHA1指纹值的文件。
在计算机上搜索所有可以找到的密钥库文件和任何备份,直到找到具有正确SHA1指纹的那个文件:
keytool -list -keystore my-release.keystore
如果提示要输入密码,只需按下Enter键即可 —— 如果您只是想快速检查SHA1值,就不必输入密码。
我找不到原始密钥库
如果您找不到原始密钥库,则永远无法发布此特定应用程序的任何更新。
Android在签署应用程序页面上明确提到了这一点:
警告:将密钥库和私钥保存在安全可靠的地方,并确保您对其进行了安全备份。 如果您将应用程序发布到Google Play,然后失去了用于签署应用程序的密钥,您将无法发布任何应用程序更新,因为您必须始终使用相同的密钥签名所有版本的应用程序。
在第一个APK发布之后,所有后续发布都必须使用完全相同的密钥进行签名。
我能从原始APK中提取原始签名密钥吗?
不行,这是不可能的。 APK仅包含公共信息,而没有您的私钥信息。
我能迁移到新的签名密钥吗?
不行。 即使您找到了原始密钥库,也不能使用密钥A签署APK,然后使用密钥A和B签署下一个更新,然后仅使用密钥B签署以后的更新。
使用多个密钥对APK(或任何JAR文件)进行签名是技术上可能的,但Google Play不再接受具有多个签名的APK。
尝试这样做将导致消息“您的APK已使用多个证书签名。 请仅使用一个证书进行签名,然后重新上传它。”
我该怎么办?
您将不得不使用新的应用程序ID构建应用程序(例如,从“com.example.myapp”更改为“com.example.myapp2”),并在Google Play上创建全新的列表。
可能您还需要更改代码,以便人们可以安装新应用程序,即使他们安装了旧应用程序,例如,您需要确保没有冲突的内容提供程序。
您将失去现有的安装基础,评论等,并且必须找到一种方法让您的现有客户卸载旧应用程序并安装新版本。
再次确保您对此版本使用的密钥库和密码进行了安全备份。