安卓Keystore停止工作了。

54

最近我遇到了一个关于密钥库的问题。我知道这个问题已经有很多相关的问答了,我已经阅读了它们并进行了激烈的谷歌搜索。

错误:

keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect
java.io.IOException: Keystore was tampered with, or password was incorrect
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:772)
    at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
    at java.security.KeyStore.load(KeyStore.java:1214)
    at sun.security.tools.KeyTool.doCommands(KeyTool.java:885)
    at sun.security.tools.KeyTool.run(KeyTool.java:340)
    at sun.security.tools.KeyTool.main(KeyTool.java:333)
Caused by: java.security.UnrecoverableKeyException: Password verification failed
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:770)
    ... 5 more

我使用的软件:

Java

java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

Eclipse

Version: 3.8.0
Build id: I20120502-2000

最新的ADT插件

最新的Android SDK

我所知道的:

  • 我没有丢失密码,也从未更改过密码。
  • 我无法检索密码(我知道这个密码)。
  • 如果不发布全新的应用程序,我无法使用其他密钥签署现有应用程序以发布更新(因此我无法发布任何更新)。

我已经做了什么:

  • 我多次卸载并重新安装了Eclipse。
  • 我多次卸载并重新安装了android ADT插件。
  • 我多次删除并重新下载了最新的Android SDK。
  • 我多次卸载并重新安装了JDK7。
  • 我尝试使用我的密钥库备份。
  • 我使用“md5sum KEYSTORE”检查了MD5校验和,并与备份进行了比较(相同的MD5输出-未篡改)。
  • 我尝试暴力破解密钥库(我已找回我所知道的密码)。
  • 我创建了一个测试密钥(使用当前设置),并测试了密码,看起来一切正常(因此某些内容发生了更改)。
  • 我尝试在Eclipse之外通过手动导出android.apk文件,然后尝试签名。

如何导出已签名的应用程序:

  • 通过Eclipse:使用文件 > 导出 > 导出Android应用程序。
  • JDK7之前:jarsigner -verbose -keystore KEYSTORE FILE ALIAS。
  • 使用JDK7:jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore KEYSTORE FILE ALIAS。

还剩下什么需要解决或尝试?

  • 有些参考/URL说要删除“trusted.certs”文件?
  • 尝试删除“debug.keystore”?
  • 更新Eclipse或任何Android开发工具是否会影响我的密钥库?
  • 从jdk6更新到jdk7是否会创建任何问题?
  • 这可能与jarsigner的运作方式有关,是否有变化?

用户建议:

  • 尝试使用JDK6,但我最近能够导出应用程序。
  • 在local.properties中检查key.store.password或key.alias.password
  • 取消Eclipse中的自动构建并清理项目
  • 尝试删除工作区中的.metadata文件夹并清除所有临时文件夹。

总结

  • 密钥库没有更改,
  • 我有密钥库的密码,
  • 最近使用以下工具成功导出应用程序:
    • Eclipse 3.8(和Eclipse 4.0+),
    • 最新的Java 7,
    • 最新的ADT插件。
  • 我的最后一次成功导出和构建是几周前使用Eclipse 3.8、最新的Android工具和Java 7,并使用相同的密码。

更新(6/29/14)


你的密钥库文件有可能已经损坏了吗?如果你有备份密钥库文件,可以尝试使用存储在其他地方的备份文件来解决问题吗? - jcw
我已经回答了这个问题。我已经检查了备份文件的MD5值以及当前文件的MD5值,看它们是否相同。我还尝试使用备份文件,但没有成功。 - Jared Burrows
我将它存储在本地,但我总是保留备份。 - Jared Burrows
我认为我可能有相同的问题。你觉得它可能是这个问题吗?(http://code.google.com/p/android/issues/detail?id=36350) - Erhannis
看起来很相似。所有事情都是在我一段时间前的更新后开始发生的。它只影响了一个应用程序。 - Jared Burrows
我得到了这个错误:为<harmankaya>输入密钥密码 keytool 错误:java.security.UnrecoverableKeyException: 无法恢复密钥 - Erhan H.
8个回答

9
可能我也遇到了同样的问题。我从来没有弄清楚为什么会失败(虽然我想知道是否因为密钥库密码少于6位数),但我能够将我的密钥复制到一个新的密钥库中,然后将其重命名以替换旧的密钥库,然后它神奇地在使用新密码后正常工作了。需要注意的是,还需要密钥密码。根据https://security.stackexchange.com/a/3795,我执行以下操作:
  1. keytool -importkeystore -srckeystore old.keystore -destkeystore new.keystore -v
  2. 两次输入新密钥库密码
  3. 当它要求我输入源密钥库密码时,按下Enter (留空)
  4. 输入密钥密码
确认新的可以工作后,我只需将其复制到旧的密钥库上。希望对您有用;祝好运。

1
我有点困惑为什么我的帖子被标记为“社区维基”。编辑:哦,等等,我明白了。问题本身被标记为“社区维基”。 - Erhannis
抱歉让你等这么久。我已经尝试过了,但每次输入密码时我都收到同样的错误信息。 - Jared Burrows
@JaredBurrows 当您尝试将密钥复制到新密钥库中时,还是当您尝试使用新密钥库时出现错误? - Erhannis
是的,它总是抱怨密码不正确。然而,当我使用暴力破解工具时,我能够找回密码。该工具能够登录/检查正确的密码。 - Jared Burrows
@JaredBurrows 抱歉,是什么在抱怨密码?是 keytool -importkeystore 命令,还是当您尝试使用复制的密钥库时?此外,当您说“该工具能够登录/检查正确的密码”时,您是指您的问题已解决,还是只是暴力破解工具确认您有正确的密码,即使 keytool 表示它不正确? - Erhannis
显示剩余5条评论

5

我曾遇到同样的问题,并尝试了帖子中提供的所有方法,但都无法保存我的别名密码。事实是,我对密码非常确定,因为我已经更新了该应用四次。我一直收到“密钥库被篡改或密码不正确”的消息。

解决方案

似乎在使用eclipse创建密钥库时,在密码之前添加了空格字符

这个讨厌的错误显然已经在后来的版本中得到修复,导致我无法使用我认为是正确的密码签署我的应用程序。

基于这个SO链接:Ant fails to build signed apk after updating to android v20 我建议你尝试在密码之前或之后添加一个空格字符


我在Unity中也遇到了同样的问题——在我的情况下是两个空格。使用复制/粘贴时必须小心!浪费了我4个小时的时间。 :( - adamgede

3
尝试删除工作区中的 .metadata 文件夹并清除所有临时文件夹。如果您的密钥库文件未损坏,并且已正确尝试重新安装 Eclipse、ADT、Android SDK 和 Java SDK,则我不认为其他原因会导致这个奇怪的问题,排除 .metadata 缓存文件和/或一些临时损坏。
另一个建议是尝试使用 Portecle —— 一个用于管理和检查密钥库、键、证书、证书请求、证书撤销列表等的实用程序。

好的,我移动了“.metadata”文件夹而不是删除它。还有哪些“temp”文件夹? - Jared Burrows
@JaredBurrows,关于其他临时文件夹,我是指您操作系统的标准临时目录。在导出过程中在该目录中创建的文件通常会在每次导出项目时生成...然而,如果您遇到此奇怪问题,那就再试一次吧。 - Silverstorm
我已经编辑了我的答案,添加了另一个建议。希望这会有所帮助。 - Silverstorm
好的,我终于有时间清除我的“.eclipse”和“.metadata”文件夹了。我重新安装了ADT插件并导入了需要导出的项目。但出于某种原因,我仍然遇到了麻烦。 - Jared Burrows

1

我建议再试几次。

耐心地应用这些步骤:

步骤:

  1. 在Eclipse中取消勾选“自动构建”(项目->自动构建),然后清理你的项目。
  2. 重新构建它。(右键单击项目+构建项目)
  3. 导出项目。
  4. 选择Android导出。(自动对齐)
  5. 选择你的密钥。提供密码。别名应该出现在列表中。(注意大小写锁定键)。有时我们会输入正确的密码,但由于大小写问题而失败;)
  6. 如果这对你有用,请告诉我。

希望这能帮到你。


好的,我已经尝试过这个,但它仍然不起作用。还是谢谢您。 - Jared Burrows

0

我的密钥别名突然停止工作了。(好的,在Android Studio和Java的几次更新后)。

我尝试了这个线程以及其他线程中的所有解决方案。在我的情况下,解决方案令人惊讶。 我有一个带有几个别名的密钥库。除了一个密码与密钥库相同的别名之外,其他别名都不起作用。但不幸的是,这不是我需要的那个。这使我毫无逻辑地思考。 我将单个别名复制到新的密钥库中

keytool -importkeystore -srckeystore old.keystore -destkeystore new.keystore -srcalias importantalias

然后我使用以下命令将别名密码更改为与密钥库密码相同:

keytool -keypasswd -keystore new.keystore -alias importantalias

终于我成功签署了我的apk文件。 这似乎是一个愚蠢的错误,可能会浪费一整天的开发时间。


这是与此线程上的“正确”答案相同的答案。 - Jared Burrows
2
我尝试了但是出现了错误, keytool 错误: java.security.UnrecoverableKeyException: 无法恢复密钥 - Erhan H.

0
我最近也遇到了这个问题,并尝试了这里和其他地方列出的所有建议。最终在我的端口识别出了一个愚蠢的错误,导致了这个错误-我想在这里分享一下,以防对你们中的任何人有所帮助。
如果您像我一样,在计算机上安装了多个Java版本,并在您最初创建密钥库的时间和现在尝试签署APK之间升级了JRE / JDK,则更有可能是这种情况。
由于某种原因,我们的编译说明引用了完整的Java路径,如下所示:
C:\ Progra〜1 \ Java \ jdk1.6.0_45 \ bin \ jarsigner-verbose-sigalg SHA1withRSA-digestalg SHA1-keystore cre80ve.keystore unsigned.apk cre80ve 以上建议之一让我想到,这可能根本不是密码问题,而是版本不兼容导致的问题。所以我运行了以下命令:
keytool-list-keystore cre80ve.keystore 使用我知道正确的密码,结果证实它是正确的密码。

然后我在路径中删除了对(旧)Java版本的显式引用。这使它自动选择最新版本的Java(在我的情况下是jdk1.8.0_31):

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore cre80ve.keystore unsigned.apk cre80ve

然后一切都开始正常工作了!

底线:问题可能根本不是密码问题,而是不同版本的Java或Android SDK引起的问题,所以记得检查一下。

一旦它开始工作,请记得将您的密钥库和密码备份到安全的地方 :-)


谢谢您的回复:“如果您和我一样,在计算机上安装了多个Java版本,并在创建密钥库后升级了JRE / JDK,那么这种情况更有可能发生,现在您正在尝试签署APK。” 我认为这就是我的情况。 - Jared Burrows

0

刚刚遇到了这个问题——突然间,Android Studio忘记了我的密码,并且不使用我在gradle文件中设置的密码。我在同一个项目中使用相同的密钥文件和密码已经有6年了!

于是我手动输入了它们,但是每次都无法通过验证。我尝试了一些方法,比如使缓存失效、重启Android Studio以及恢复密钥库的备份,但都没有帮助。

最后,在绝望中,我尝试交换密钥库密码和密钥密码。结果——它奏效了!原来几年前我在输入它们到Gradle构建文件时已经交换了密码,但出于某种原因我从未注意到。

结论:永远不要100%确定你做得对。


0

你是否将诸如key.store.password或key.alias.password等值存储在local.properties文件中? 它们中有任何一个是不正确的吗?

我很好奇使用JDK6创建并在JDK7中进行验证时是否存在某些错误,这可能会解释为什么您为测试创建的新密钥可以运行,但旧密钥无法正常工作。尝试降级到JDK6并查看是否可以解决问题-其他人在JDK7中遇到了jarsigner的问题,当他们降级到6时,问题就消失了。如果这行得通,请提交bug报告并要求修补程序,以便您可以安全地升级到Java 7 :)


抱歉回复晚了,但我怎么会意外地将这些值存储在local.properties中呢?另外,你是指project.properties而不是local.properties吗? - Jared Burrows
这些值可以读取其中之一。local.properties 用于存储特定于您的机器的值,不应该进入源代码管理中(例如 SDK 路径、密钥库文件路径等)。project properties 是用于存储与机器无关的键/值对,如最小/目标 API 版本。 - Alexander Lucas
我查了一下,发现这些文件并没有在我的本地电脑上找到。 - Jared Burrows

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接