6

在 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。

这个问题类似于这个没有答案的问题,但我从 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 项目并Archive...按照这些说明单击。

作为旁注,微软的那篇文章非常令人沮丧,因为它没有提到签名或这个问题,而且他们关于签名的文章与 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 RunMSBuild project build output verbosityMinimalto更改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 Package Signing 选项卡中的(编辑的)值是什么。通过反复试验,我发现 Keystore 密码、别名和别名密码都是必需的。我将密钥库密码和别名密码设置为相同,因为只有一个密码与此密钥库关联。如上所述,密码是低字母数字(根据另一个 SO 问题的建议没有特殊字符)。

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

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

4

4 回答 4

3

我已经找到了我的问题的答案。Android 开发者网站上的文档不适用于 Visual Studio。Xamarin 附带的 ApkSigner 不知道如何处理它。相反,使用它来创建您自己的发布密钥:

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

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

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

线索

当我按照文档上的说明进行操作时,我收到了来自以下位置的警告keytool

警告:JKS 密钥库使用专有格式。建议迁移到 PKCS12,这是一种使用keytool -importkeystore -srckeystore c:\temp\myreleasekey.jks -destkeystore c:\temp\myreleasekey.jks -deststoretype pkcs12.

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

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

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

谢谢:

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

谢谢你,乔恩,指点我如何创建我自己的私钥。

于 2018-07-24T16:38:07.250 回答
2

您缺少的重要事实:

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

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

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

为什么谷歌不给你签名密钥?

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

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

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

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

如果我丢了怎么办?

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

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

于 2018-07-24T07:41:51.833 回答
0

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

你会得到这个选项

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

例子

于 2021-01-25T06:53:31.097 回答
0

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

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

于 2021-02-19T11:51:14.213 回答