apk必须使用与以前版本相同的证书进行签名

我前一段时间曾将我的应用程序上传到Google Play(当时称为Android Market)。

今天我更新了应用程序,但我删除了以前的密钥库并创建了一个新的密钥库。
上传时,它表示APK必须使用与以前版本相同的证书进行签名:

上传失败

您上传了使用其他证书签名的APK到以前的APK。 您必须使用相同的证书。

您现有的APK使用带有指纹的证书进行签名:
[SHA1:89:2F:11:FE:CE:D6:CC:DF:65:E7:76:3E:DD:A7:96:4F:84:DD:BA:33]
并且用于签署您上传的APK的证书有指纹(s):
[SHA1:20:26:F4:C1:DF:0F:2B:D9:46:03:FF:AB:07:B1:28:7B:9C:75:44:CC]

但是我没有这个证书,也不想删除和重新发布应用程序,因为它有活跃的用户。

我可以做什么用新证书签署我的应用程序?

没有。 阅读文档: 在Android Market上发布更新

在上传更新的应用程序之前,请确保已经在清单文件的元素中增加了android:versionCode和android:versionName属性。 另外,软件包名称必须相同, .apk必须使用相同的私钥签名。 如果软件包名称和签名证书与现有版本不匹配,Market会将其视为新的应用程序,不会将其作为更新提供给用户。

您是否错误地使用了调试密钥?

Google Play不允许您发布使用您的调试密钥库签名的应用程序。 如果您尝试上传这样的APK,Google Play将会失败,并显示“您上传的APK版本是以调试模式登录的,您需要在发布模式下对APK进行签名”。

但是,如果尝试上载使用调试密钥库签名的更新 ,则不会看到此消息。 Google Play会根据SHA1指纹显示问题中显示的信息。

因此,首先,请检查您是否错误地用您的调试密钥签署了应用程序。


如何检查使用哪个签名密钥?

收集APK中的信息

您可以使用Java keytool通过使用这些命令来检查原始APK和更新APK是使用哪个证书进行签名的:

 keytool -list -printcert -jarfile original.apk keytool -list -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之间的所有者,SHA1和到期值

  • 如果所有者 / X.509身份值是CN=Android Debug, O=Android, C=US ,那么您已经使用您的调试密钥对APK进行了签名,而不是原始的释放密钥

  • 如果原始和更新APK之间的SHA1指纹值不同,那么您对两个APK都没有使用相同的签名密钥

  • 如果所有者 / X.509身份值不同,或者两个APK之间的证书失效日期不同,则您没有对两个APK使用相同的签名密钥

请注意,即使两个证书之间的所有者/ X.509值相同,这并不意味着证书是完全相同的 – 如果有其他内容不匹配 – 例如指纹值 – 则证书是不同的。


搜索原始密钥库,检查备份

如果两个APK具有不同的证书信息,则必须找到原始的密钥库,即具有Google Play(或keytool )告诉您的第一个SHA1指纹值的文件。

搜索您可以在计算机上找到的所有密钥库文件,以及您拥有的任何备份,直到找到具有正确SHA1指纹的文件为止:

 keytool -list -keystore my-release.keystore 

如果提示输入密码,只需按Enter键 – 如果您只想快速检查SHA1值,则不必输入密码。


我无法在任何地方找到原始的密钥存储

如果您找不到原始密钥库,则永远无法发布对此特定应用程序的任何更新。

Android在Signing Your Application页面上明确提到了这一点:

警告:请将密钥库和专用密钥放在安全可靠的地方,并确保您有安全的备份。 如果您将应用发布到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上创建一个全新的列表。

可能你也必须改变你的代码,以便人们可以安装新的应用程序,即使他们已经安装了旧的应用程序,例如你需要确保你没有冲突的内容提供者。

您将失去现有的安装基础,评论等,并将不得不找到一种方法让现有的客户卸载旧的应用程序并安装新版本。

再次确保您有用于此版本的密钥库和密码的安全备份。

没有什么 – 谷歌很清楚地表明,应用程序是由用来签名的密钥来标识的。 因此,如果你失去了密钥,你需要创建一个新的应用程序。

如果你有以前的apk文件(备份),然后使用jarSigner从apk中提取证书,然后使用该密钥或使用keytool克隆该证书,可能会有所帮助…有用的链接是jarsigner文档和keytool文档 。

在这里,我得到了这个问题的答案。 最后,我搜索了太久之后,我就破解了密钥和密码。 我忘记了我的密钥和别名也jks文件,但幸运的是我知道我已经把它放在一堆密码。 但找到正确的组合对我来说是最艰巨的任务。

解决方案 – 下载这个 – Keytool IUI版本2.4.1插件 在这里输入图像描述

窗口将弹出现在它显示别名..如果你的jks文件是正确的..右键单击别名,并点击“查看证书链”..它会显示SHA1键..匹配此键与你所得到的关键当你在谷歌应用程序商店上传apk

如果匹配,那么你是正确的jks文件和别名..

现在幸运,我有一堆密码匹配.. 在这里输入图像描述

现在去这个scrren把相同的jks路径..和密码(你有密码之间)把任何路径在“证书文件”

如果屏幕显示任何错误,那么密码不匹配..如果它不显示任何错误,那么这意味着你是正确的jks文件。 正确的别名和密码()现在与你可以上传你的apk在Play商店:)

今天,我面临同样的问题,不幸的是,我在我的密钥库文件中有两个别名。 在这里输入图像描述