【问题标题】:Visual Studio's AndroidApkSigner does not find key in keystoreVisual Studio Android ApkSigner 在密钥库中找不到密钥
【发布时间】:2018-07-23 14:33:39
【问题描述】:

在 Visual Studio 中创建 APK 时出现此错误:

Failed to load signer "signer #1": C:\...\googleplay.keystore entry "googleplay" does not contain a key

我是一名熟悉 Visual Studio 的长期 ASP.NET 开发人员,但这是我的第一个 Xamarin 项目。 (我没有使用 Android Studio。)我正在尝试将 Android 构建部署到 Google Play。我从未将 APK 上传到 Google Play,因此无法使用 Visual Studio 的自动部署;我必须先按照 Google 和 Microsoft 的说明执行手动部署。

我正在运行带有 JDK 1.8 的 Visual Studio 2017 15.7.5(最新)。我的项目使用的是 NETStandard.Library 2.0.3、Xamarin.Forms 3.1.0 和 Microsoft.EntityFrameworkCore 2.1.1。

这个问题类似于this question that has no answers,但我从 Visual Studio 中得到了错误。如果这是重复的,我很抱歉,但我无法添加有关该问题的其他详细信息。

我正在使用 Google Play 应用签名。我通过 Google Play 创建了一个密钥。我下载了 .der 格式的证书。我使用 keytool(来自 c:\Program Files\Java\jdk1.8.0_172\bin)通过以下命令将 .der 文件转换为 .keystore:

keytool -importcert -alias googleplay -file "C:\...\deployment_cert.der"

我已经重新运行此实用程序几次更改选项,认为可能存在 keytool 提示输入的密码中的别名或特殊字符的区分大小写问题。在这种情况下,别名全部是字母,全部小写,密码是字母数字全部小写。 keytool 要求信任此证书,我按“y”。

这会生成一个名为 .keystore 的文件。我将其重命名为googleplay.keystore,并将其移至更合适的位置。

我可以通过运行以下命令再次检查 googleplay 别名是否存在于密钥库文件中:

C:\Program Files\Java\jdk1.8.0_172\bin>keytool -v -list -keystore "C:\...\googleplay.keystore" -alias googleplay
Enter keystore password:
Alias name: googleplay
Creation date: Jul 23, 2018
Entry type: trustedCertEntry

Owner: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Issuer: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Serial number: e8************************************8a
Valid from: Thu Jul 19 14:18:56 EDT 2018 until: Sun Jul 19 14:18:56 EDT 2048
Certificate fingerprints:
         MD5:  0D:**:**:**:**:**:**:**:**:**:**:**:**:**:**:C8
         SHA1: 11:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:CD
         SHA256: D0:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:74
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

“googleplay”别名绝对存在!证书指纹与 Google 给我的密钥相匹配(已编辑)。

在 Visual Studio 中,我将解决方案配置设置为发布模式,我清理了我的整个解决方案(成功),重建了我的整个解决方案(成功),然后右键单击我的 Android 项目并单击these instructionsArchive... .

附带说明一下,那篇 Microsoft 文章非常令人沮丧,因为它没有提及签名或这个问题,而且他们在 signing 上的 articles 与 Google Play 的运作方式不匹配,并且似乎假设您拥有正确的 APK已上传到 Google Play(绕过先有鸡还是先有蛋的 Catch-22)。

起初我得到的只是The archiving process has failed. Please see the Errors section for more details. 错误列表面板是空的。输出面板只是说"java.exe" exited with code 2. 我去了Tools -> Options -> Projects and Solutions -> Build and Run 并将MSBuild project build output verbosityMinimal 更改为Diagnostic 并重复最后几个步骤(清理、重建、存档)。现在,输出面板(略有编辑)说:

Using "AndroidApkSigner" task from assembly "C:\...\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll".
Task "AndroidApkSigner"
AndroidApkSigner:
  ApkSignerJar: C:\Program Files (x86)\Android\android-sdk\build-tools\27.0.3\lib\apksigner.jar
  ApkToSign: bin\Release\com.mycompany.myproject.apk
  ManifestFile: obj\Release\android\AndroidManifest.xml
  AdditionalArguments: 
C:\Program Files\Java\jdk1.8.0_172\\bin\java.exe -jar "C:\Program Files (x86)\Android\android-sdk\build-tools\27.0.3\lib\apksigner.jar" sign --ks "C:\...\googleplay.keystore" --ks-pass pass:******** --ks-key-alias googleplay --key-pass pass:******** --min-sdk-version 19 --max-sdk-version 27  C:\...\myproject.Android\bin\Release\com.mycompany.myproject.apk 
Failed to load signer "signer #1": C:\...\googleplay.keystore entry "googleplay" does not contain a key
"java.exe" exited with code 2.
Done executing task "AndroidApkSigner" -- FAILED.
Done building target "_Sign" in project "myproject.Android.csproj" -- FAILED.
Done building project "myproject.Android.csproj" -- FAILED.
Build FAILED.

从上面的输出中,您可以看到我的项目属性的 Android 包签名选项卡中的(编辑的)值是什么。通过反复试验,我发现 Keystore 密码、别名和别名密码都是必需的。我将密钥库密码和别名密码设置为相同,因为只有一个密码与此密钥库关联。如上所述,密码是小写字母数字(根据另一个 SO 问题的建议没有特殊字符)。

为什么当 keytool 没有问题地找到密钥时,AndroidApkSigner 无法在提供的别名的密钥库中找到密钥?

而且,我不能是唯一有这个问题的人吗?从 Visual Studio 部署到 Google Play 应该是一个相当常见的工作流程,但我没有找到遇到此问题的其他任何人(除了 this other unanswered SO question)。我做错了什么?

【问题讨论】:

  • 15.6, signing is broken开始。我什至无法再将我的 xamarin 应用程序部署到物理设备上进行调试。
  • 在上传到 Google Play 之前,您是如何生成应用的密钥库/密钥的?如果这是一个新应用程序,您无需执行任何操作,只需上传 Release APK。当您选择加入应用签名计划时,用于发布 APK 的密钥将成为上传密钥,然后 Google Play 将生成一个新密钥以在 APK 到达用户之前对其进行签名。
  • @JonDouglas,我创建的第一个 APK 没有签名。 VS 创建的很好,但是当我将它上传到 Google 时,它​​说 APK 不是 zip-aligned,这导致我使用 zipalign.exe。我将它上传到 Google,然后它说需要对 APK 进行签名,这与 this page 一致,即“需要 Google Play 的应用签名”。这把我带到了这里。我选择了 Google Play App Signing,它给了我一个证书(问题中描述的 .der 文件)。我应该做一些不同的事情吗?
  • 您应该能够上传使用本地密钥库签名的发布 APK。该存储中的密钥将成为上传密钥。然后,它将生成一个新的上传密钥,该密钥与原始密钥一致,以供将来任何 APK 更新使用。
  • 好的,我刚刚创建了自己的独立于 Google Play 的 .keystore。 keytool -genkeypair -v -keystore mykey.keystore -alias eric -keyalg RSA -keysize 2048 -validity 10000。我更新了我的项目以使用此密钥库。清理、重建、存档,然后我得到一个与上面详述的类似的错误:Failed to load signer "signer #1",但这次它在下一行显示,java.io.IOException: Failed to obtain key with alias "eric" from C:\...\mykey.keystore. Wrong password? 如上面的问题,我可以验证别名“eric”是否存在和密码是正确的。

标签: visual-studio xamarin.android google-play keytool apksigner


【解决方案1】:

我已经找到了我的问题的答案。 documentation on the Android Developer site 不适用于 Visual Studio。 Xamarin 附带的 ApkSigner 不知道如何处理它。相反,使用它来创建您自己的发布密钥:

keytool -v -list -keystore c:\temp\myreleasekey.keystore -alias myalias -storetype pkcs12

注意最后的-storetype pkcs12。此命令也被修改为 (1) 将文件写入 Program Files 之外的某个位置,(2) 使用 Visual Studio 喜欢的 .keystore 扩展名,以及 (3) 避免 Visual Studio 不喜欢的别名中的特殊字符,从什么我读了。 (也避免密码中出现特殊字符。)

注意,keytool 位于c:\Program Files\Java\jdk[version]\bin

线索

当我按照the documentation 上的说明进行操作时,我收到了来自keytool 的警告:

警告: JKS 密钥库使用专有格式。建议迁移到使用keytool -importkeystore -srckeystore c:\temp\myreleasekey.jks -destkeystore c:\temp\myreleasekey.jks -deststoretype pkcs12 的行业标准格式PKCS12。

验证密钥是否正确时,我也收到此警告:

keytool -v -list -keystore c:\temp\myreleasekey.jks -alias myalias

如果您有现有的密钥并需要对其进行转换,请按照警告中的命令进行操作。

谢谢:

我要感谢 Nick 解释签名和区分所有密钥的原因。

感谢 Jon 为我指出如何创建自己的私钥。

【讨论】:

  • 我收到错误异常“别名 XX 不存在”
【解决方案2】:

你遗漏的重要事实:

Google Play 绝不会为您提供用于签名的密钥。它只会为您提供用于验证的证书。

我将从您可能知道的基础知识开始。在公钥密码学中,有一个私钥和一个公钥。只有签名的人拥有私钥。否则任何人都可以签名。任何人都可以拥有的公钥。他们可以使用它来检查签名是否有效。

upload_cert.der 下载仅包含公钥。 Google Play 允许您下载它以进行验证的原因。您可以离线验证您的签名是否符合 Play 商店的预期。你可能永远不需要这样做。

为什么 Google 不给你签名密钥?

Google Play 没有为您提供上传证书的私钥,原因有两个。

  1. Google 没有您上传密钥的私有部分!您在注册 Google Play 应用签名时创建了上传密钥的私钥部分。你从来没有把它交给谷歌。 Google 拥有的只是公钥部分。
  2. 如果 Google 确实将其提供给您,那么该密钥将毫无价值。上传密钥的全部意义在于,即使黑客闯入您的 Play 管理中心帐户,他们仍然无法上传您应用的新版本。他们也需要上传密钥。上传密钥意味着 Google Play 知道该应用来自您。如果他们让您从您的帐户下载签名密钥,那么黑客也可以下载它。那它就一文不值了。

如何获取签名所需的上传密钥?

所以现在您可能遇到的问题是“我如何获得签名所需的公钥?”。答案是“你创造它”。当您第一次上传您的 APK 时,该 APK 已使用密钥签名(Google 坚持这样做)。它可能存储在您的 Visual Studio 中。该密钥成为您的上传密钥。找到你保存它的地方。

万一我丢了怎么办?

现在您可能不知道您最初使用的密钥在哪里。这是 Google Play 应用签名的伟大之处。如果您自己对应用程序进行签名并丢失了签名密钥,您将被卡住,您必须创建一个新应用程序。但是通过 Google Play 应用签名,您可以联系 Play 管理中心支持,他们可以为您提供帮助。 The process is on the help page.

查看标题为“创建新的上传密钥”的部分。请注意,第 1 步是您创建密钥。 Google 仍然没有。

【讨论】:

  • 谢谢你的解释,尼克。我是 Google Play 的新手,因此,正如您所写,我需要创建自己的密钥(我没有丢失任何东西)。您的链接将我带到this page。这有点难以理解,因为它适用于 Android Studio,而不是 Visual Studio。此外,正如我在上面写信给 Jon Douglas 的那样,我创建了自己的密钥(有关详细信息,请参见上文;我按照此链接中的 keytool 说明进行操作),但 ApkSigner 仍然不喜欢它。我究竟做错了什么?我该怎么做?
  • 在您链接到的页面下方是“从命令行构建并签署您的应用程序”部分developer.android.com/studio/publish/app-signing 这提供了生成密钥和在命令行上签署 APK 的说明。这有帮助吗?
  • “从命令行构建并签署您的应用程序”正是我在上面写给 Jon 时所遵循的。我已经做到了。我将 Visual Studio 设置为使用我制作的这个密钥。构建 APK 时,ApkSigner 无法在密钥库中找到密钥。
【解决方案3】:

禁用选项“使用以下密钥库详细信息签署 .APK 文件。

你会得到这个选项

右键单击android项目选择properties转到Android Package Signing

【讨论】:

    【解决方案4】:

    对我来说,这个问题与包装/签名屏幕有关。我最终从签名屏幕中删除了所有内容,然后构建了存档。

    构建完成后,我点击存档并点击分发。此时它要求我提供密钥库和密码。我输入了它们并签署了apk。我用那个来侧载应用程序,效果很好。

    【讨论】:

      猜你喜欢
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 2019-04-12
      • 2022-01-24
      • 2019-04-03
      • 2017-02-26
      相关资源
      最近更新 更多