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

Posted

技术标签:

【中文标题】apk 必须使用与之前版本相同的证书进行签名【英文标题】:The apk must be signed with the same certificates as the previous version 【发布时间】:2011-01-30 13:39:12 【问题描述】:

不久前,我已将我的应用上传到 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 的证书有指纹: [SHA1:20:26:F4:C1:DF:0F:2B:D9:46:03:FF:AB:07:B1:28:7B:9C:75:44:CC]

但我没有此证书,也不想删除并重新发布该应用程序,因为它有活跃用户。

如何使用新证书签署我的应用程序?

【问题讨论】:

我遇到了不同的问题:我尝试升级应用程序,但它让我一直说这个错误。事实是,我从未更改过密钥库!!!我该怎么办?!? 你是怎么解决的?? @int_32 你是怎么解决的?? 【参考方案1】:

什么都没有。阅读文档:Publishing Updates on Android Market

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

【讨论】:

很好的答案。我从来没有意识到如果密钥丢失,那么应用程序将无法更新。必须记住将密钥备份在安全的地方。 我通常会做的是将密钥库文件存储在svn中。放置一个名为 credential 的新文件夹以及 trunk/tag/branches,并将密钥库文件存储在那里。还要添加一个新的 .txt 文件来指示密钥库文件。 Keystore 与源代码一样重要。一旦你丢失了它(或忘记了密码),你就完蛋了.. 正如@Krishnabhadra 所说,不要将您的密钥库密码(或与此相关的任何密码)检查到源代码控制中。将密钥库和密码分开,并确保密码安全。 什么?!但它只是告诉我我的密钥太旧了,所以我删除了它并创建了一个新的,现在我得到了这个!? @iwayneo 构建系统可能会告诉您您的 debug 密钥太旧,但使用 release 密钥不太可能发生这种情况,因为 Google Play 应该拒绝在 October 2033 之前过期的密钥。【参考方案2】:

你是不是误用调试密钥签名了?

Google Play 不允许您发布使用调试密钥库签名的应用。如果您尝试上传此类 APK,Google Play 将失败并显示消息“您上传的 APK 在调试模式下签名。您需要在发布模式下签名您的 APK。”

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

首先,检查你是否错误地使用调试密钥签署了应用程序。


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

从 APK 中收集信息

您可以使用这些命令检查原始 APK 和更新 APK 使用哪些证书签名,使用 Java keytool

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 身份值和有效期自/直到 strong> 日期。


如果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,那么您已经使用 debug 签署了 APK键,而不是原来的释放键

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

如果 Owner/X.509 身份值不同,或者两个 APK 的证书到期日期不同,那么您没有 对两个 APK 使用相同的签名密钥

请注意,即使两个证书之间的 Owner/X.509 值相同,这并不意味着证书相同 - 如果其他任何内容不匹配 - 例如指纹值 - 那么证书是不同的.


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

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

搜索您可以在计算机上找到的所有密钥库文件,以及在您拥有的任何备份中,直到找到具有正确 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 上创建一个全新的列表。

您可能还必须更改代码,以便人们可以安装新应用,即使他们安装了旧应用,例如您需要确保没有冲突的内容提供者。

您将失去现有的安装基础、评论等,并且必须想办法让现有客户卸载旧应用并安装新版本。

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

【讨论】:

我已经尝试过你给出的命令,用于检查调试(我实际上正在搜索),但它返回一个错误,即 jar 包含不包含时间戳的签名。我使用这个线程创建了我的 apk:***.com/questions/16622843/… @RageCompex 你没有得到任何输出,只有一个错误吗?当我运行该命令时,我还会收到时间戳警告(不是错误)。只要您获得 X.509 输出,这就是您所需要的。 是的,我确实得到了 X.509 输出,所以我猜这不是问题吗? [CertPath not validated: Path does not chain with any of the trust anchors] 怎么样,不是问题吗?我确实在CN 看到了我的名字,所以我想我正确地签名了:) @RageCompex 这已经在“检查使用的签名密钥”部分得到解答。 我今天心脏病发作了。我使用这些命令行来找出隐藏的密钥库。非常感谢,伙计!你救了我……真的:D【参考方案3】:

什么都没有 - 谷歌明确表示,应用程序是由用于签名的密钥识别的。因此,如果您丢失了密钥,则需要创建一个新应用程序。

【讨论】:

@sports 他们警告你。注意大红色 警告 消息:developer.android.com/tools/publishing/… @sports 无论如何,您可以在同一个开发者帐户上发布多个应用程序,因此您无需再次付费。【参考方案4】:

我只是突然发生了这种情况。我真的不认为我改变了什么。

但是,Build => Clean Project 修复了它。

【讨论】:

嗯,我已经花了 1 周时间,尽了一切可能。是时候说“WTF”了,但这是唯一有帮助的事情。 (我也尝试过无效的缓存,但没有帮助..)谢谢 这解决了疯狂一小时后的问题 我不认为这是相关的。 非常感谢!我不小心生成了一个带有不同密钥库文件和凭据的签名 apk 并将其上传。即使在使用正确的密钥库上传 apk 后仍会出现相同的错误。经过一个小时使用无效缓存创建新版本,android studio 和 PC 重新启动,这终于修复了它。 经过大量的尝试和尝试,我得到了这个答案,神奇地它对我有用,但仍在弄清楚如何!【参考方案5】:

今天我遇到了同样的问题,不幸的是,我的密钥库文件中有两个别名。

【讨论】:

【参考方案6】:

我在这里得到了那个问题的答案。在搜索了太久之后,我终于破解了这个密钥和密码。我忘记了我的密钥和别名以及 jks 文件,但幸运的是我知道我输入的一堆密码。但找到正确的组合对我来说是最艰巨的任务。

解决方案 - 下载这个 - Keytool IUI 2.4.1 版插件

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

如果匹配,那么您使用正确的 jks 文件和别名 ..

现在幸运的是我有一堆密码可以匹配..

现在转到这个 scrren 输入相同的 jks 路径 .. 和密码(在您拥有的密码中)将任何路径放入“证书文件”中

如果屏幕显示任何错误,则密码不匹配。如果没有显示任何错误,则表示您的 jks 文件正确。正确的别名和密码() 现在,您可以在 Play 商店中上传您的 apk :)

【讨论】:

您丢失了私钥并且可以通过这种方式找回它?如果答案是肯定的,您是否可以链接到哪里下载该工具?以及如何打开应用程序? 像魅力一样工作,达到了我的目的。感谢分享。【参考方案7】:

我强烈推荐 Keystore Explorer (https://keystore-explorer.org/),它可以让您访问您的密钥库,而无需将其上传到 Google Play。这样您就可以排查您是否输入了错误的密码。

【讨论】:

【参考方案8】:

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

【讨论】:

"..use jarSigner to extract certificate from that apk" - 告诉我们怎么做? 这不会恢复你需要再次签署apk的私钥。 Apk 必须使用相同的私钥签名【参考方案9】:

我最近遇到了这个问题,在尝试了不同的登录方式(例如启用 V1 或 V2)后,通过更改别名登录,最后知道我使用了错误的密钥存储文件

【讨论】:

【参考方案10】:

您可以使用新功能 Google Play 应用签名来生成新的密钥文件。

在 2017 年 5 月之后,Google Play 商店在 Play 商店中添加了一项新功能,并且 这对 Android 开发者来说是个好消息。 通过此功能,开发人员可以更新丢失 KeyStore 文件的应用或 Apk。 您需要在 Play 商店控制台上启用 Google Play 应用签名。

https://support.google.com/googleplay/android-developer/answer/7384423?hl=en

http://www.geekcodehub.com/2018/05/23/keystore-lost-in-android/

【讨论】:

这不能回答问题。【参考方案11】:

我的 [愚蠢] 错误是我使用了 app-debug.apk 文件而不是 app-release.apk 文件。 生成签名 APK 时,需要在“Build Variants”框架中选择“release”。 app-release.apk 文件应位于项目根目录的“app\release”文件夹下。

【讨论】:

以上是关于apk 必须使用与之前版本相同的证书进行签名的主要内容,如果未能解决你的问题,请参考以下文章

签名证书丢失密码

Google Play 上新版本应用的上传失败并出现签名错误

无法使用 Google Play 应用签名上传证书更新发布 APK(使用原始密钥库)

Android 签名密钥库

Android ------ apk签名时出现找不到证书链

Android ------ apk签名时出现找不到证书链