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

int*_*_32 188 android apk google-play

不久前我将我的应用程序上传到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]

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

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

Rub*_*con 180

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

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

  • 请****不要**检查您的密钥库密码(或任何密码)到源代码管理中,正如@Krishnabhadra所说.保持密钥库和密码分开,密码安全. (36认同)
  • 我通常会做的是将密钥库文件存储在svn中.放置一个名为credential的新文件夹,以及trunk/tag/branches,并将密钥库文件存储在那里.还要添加一个新的.txt文件,指示密钥库文件.**密钥库与源代码**一样重要.一旦你丢失它(或忘记了密码),你就是SCREWED .. (17认同)
  • 很好的答案.我从未意识到如果密钥丢失,那么应用程序无法更新.必须牢记在安全的地方备份密钥. (9认同)
  • 什么?!但它只是告诉我我的密钥太旧了,所以我删除了它并创建了一个新密钥,现在我明白了!? (2认同)
  • @iwayneo构建系统可能已经告诉你,你的**debug**键太旧了,但是发布**键的可能性很小,因为Google Play应该拒绝在[2033年10月]之前过期的密钥(https://developer.android.com/tools/publishing/preparing.html#publishing-keys). (2认同)

Chr*_*Orr 116

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

Google Play不允许您发布使用调试密钥库签名的应用.如果您尝试上传此类APK,Google Play将会失败,并显示"您上传了以调试模式签名的APK.您需要在发布模式下签署您的APK".

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

首先,检查您是否错误地使用调试密钥对应用程序进行了签名.


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

从APK收集信息

您可以使用以下Java命令检查原始APK和更新APK使用这些命令签署的证书keytool:

keytool -list -printcert -jarfile original.apk
keytool -list -printcert -jarfile update.apk
Run Code Online (Sandbox Code Playgroud)

这会向您显示有关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
Run Code Online (Sandbox Code Playgroud)

这里要注意的重要部分 - 对于每个APK - 是SHA1指纹值,所有者身份值和有效期自/直到日期.


如果该keytool命令不起作用(该-jarfile选项需要Java 7),您可以通过以下jarsigner命令获取更多基本信息:

jarsigner -verify -verbose:summary -certs original.apk
jarsigner -verify -verbose:summary -certs update.apk
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这并未显示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]
Run Code Online (Sandbox Code Playgroud)

您可以忽略任何"CertPath not validated"消息,以及有关证书链或时间戳的警告; 在这种情况下,它们不相关.

比较APK之间的所有者,SHA1和到期值

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

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

  • 如果业主/X.509标识值是不同的,或证书失效日期两个之间的APK不同,那么你是不是使用两个的APK相同的签名密钥

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


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

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

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

keytool -list -keystore my-release.keystore
Run Code Online (Sandbox Code Playgroud)

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上创建一个全新的列表.

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

您将丢失现有的安装基础,评论等,并且必须找到一种方法让现有客户卸载旧应用并安装新版本.

同样,确保您拥有用于此版本的密钥库和密码的安全备份.

  • 我今天心脏病发作了。我使用这些命令行来找出隐藏的密钥库。非常感谢,伙计!你救了我...真的:D (2认同)

Eug*_*its 8

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

  • @sports 在任何情况下,您都可以在同一个开发者帐户上发布多个应用程序,因此您无需再次付费。 (2认同)

Dav*_*ard 8

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

不过,Build => Clean Project修好了。

  • 我不认为这有关系。 (2认同)

Kri*_*han 6

今天我遇到了同样的问题,不幸的是,我的密钥库文件中有两个别名.在此输入图像描述


小智 5

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

解决方案 - 下载这个 - Keytool IUI 2.4.1 版插件 在此处输入图片说明

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

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

现在幸运的是我有一堆密码可以匹配.. 在此处输入图片说明

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

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


drd*_*div 5

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


Dev*_*ddy 5

请检查您的android/app/build.gradle文件

android{
    ...
    buildTypes {
        release {
        // signingConfig signingConfigs.debug
           signingConfig signingConfigs.release
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

在发布应用程序包之前,应该启用signingConfig signingConfigs.release此行而不是signingConfig signingConfigs.debug此行。

我犯了这个愚蠢的错误。

我正在其他设备上测试我更新的应用程序,方法是使用 发布它,debug sign in config当我准备发布更新时,我没有更改配置并发布了具有调试配置的捆绑包。

在摸索了大约一个小时后,我意识到我一直都有这个问题debug config,然后我将其更改为release mode现在问题已解决。