您是否错误地使用调试密钥签名?
谷歌Play不允许您发布使用调试密钥库签名的应用程序。如果您尝试上传这样一个APK,谷歌播放将失败,并提示“您上传了一个在调试模式下签名的APK。你需要在释放模式下签署APK。”
但是,如果您尝试上传使用调试密钥库签名的更新,则不会看到此消息;谷歌播放将显示问题中所示的消息,指的是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指纹值、所有者身份值和有效日期。
如果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之间的Owner、SHA1和Expiry值
如果Owner/X.;509的身份值为CN=Android Debug, O=Android, C=US,那么您已经用您的调试密钥签署了APK,而不是原始的发布密钥
如果原始apk和更新apk之间的SHA1指纹值不同,则您没有对两个apk使用相同的签名密钥
如果Owner/X.;509身份值不同,或者两个apk之间的证书到期日期不同,则您没有对两个apk使用相同的签名密钥
注意,即使Owner/X。509的值在两个证书之间是相同的,这并不意味着证书是相同的-如果其他任何地方不匹配-例如指纹值-那么证书是不同的。
搜索原始密钥存储库,检查备份
如果两个apk具有不同的证书信息,则必须找到原始的密钥存储库,即谷歌Play(或keytool)告诉您的具有第一个SHA1指纹值的文件。
搜索您在计算机上可以找到的所有密钥存储库文件,以及您拥有的任何备份,直到您拥有具有正确SHA1指纹的密钥存储库文件:
keytool -list -keystore my-release.keystore
如果提示输入密码,只需按Enter -如果只是想快速检查SHA1值,则不必输入密码。
我在任何地方都找不到原始的密钥存储库
如果找不到原始的密钥存储库,就永远无法向这个特定的应用程序发布任何更新。
Android在Signing Your Application页面中明确提到了这一点:
警告:将您的密钥存储库和私有密钥保存在一个安全的地方,并确保您有它们的安全备份。如果你发布一个应用到谷歌Play,然后丢失了你签名应用程序的密钥,你将不能发布任何更新到你的应用程序,因为你必须总是用相同的密钥签名你的应用程序的所有版本。
在APK的第一个发行版之后,所有后续发行版都必须使用完全相同的密钥进行签名。
我可以从原始APK中提取原始签名密钥吗?
不。这是不可能的。APK只包含公共信息,不包含您的私钥信息。
我可以迁移到新的签名密钥吗?
不。即使您找到了原始版本,也不能使用密钥A签署APK,然后使用密钥A和B签署下一次更新,然后仅使用密钥B签署下一次更新。
使用多个密钥对APK(或任何JAR文件)进行签名在技术上是可行的,但谷歌Play不再接受具有多个签名的APK。
尝试这样做将导致消息“您的APK已使用多个证书进行签名。请只签署一个证书,并重新上传。”
我该怎么办?
你必须用一个新的应用程序ID来构建你的应用程序(例如从“com.example”更改。myapp”到“com.example.myapp2”),并在谷歌Play上创建一个全新的列表。
可能你还需要改变你的代码,以便人们可以安装新的应用程序,即使他们已经安装了旧的应用程序,例如,你需要确保你没有冲突的内容提供者。
你将失去现有的安装基础和评论等,并必须找到一种方法让现有客户卸载旧应用并安装新版本。
同样,请确保您拥有此版本所使用的密钥存储库和密码的安全备份。