使用 Adob​​e Air 证书签署 Android 本机 apk

Sign Android Native apk with Adobe Air certificate

我需要帮助使用为 Adob​​e Air 生成的现有 .p12 证书对 Android 本机应用程序进行签名。应用程序是几年前在 Adob​​e Air 中完成的,签署并发布到 Google play。现在,当从 Adob​​e Air 迁移到 Android Native 时,为了将应用程序升级到商店中的新版本,需要使用相同的私钥对其进行签名。问题是在 java 的较新版本上无法通过 keytool open/read 密钥。尝试读取 .p12 证书将 return:

java.security.cert.CertificateException: Unable to initialize, java.io.IOException: DerInputStream.getLength(): Redundant length bytes found

keytool error: java.io.IOException: Invalid keystore format

取决于我尝试执行的命令。

(1) 向老友请教Google 没有带来多少,反而有更多的无奈。我确实喜欢 jira ticket of openjdk 中的建议,我尝试使用 OpenSSL 以这种方式修复冗余字节:

openssl pkcs12 -in pkcs12-file -out key-and-cert -nodes -passin pass:abcXYZ 
openssl pkcs12 -in key-and-cert -export -out new-pkcs12-file -passout pass:abcXYZ

此命令将成功执行,但是,生成的 SHA1 密钥 (...:F7) 将与原始密钥 (...:E5) 不同!这实际上并不奇怪,因为更改文件的任何部分(如删除冗余字节)将以不同的 SHA 密钥结束。好的,很明显这不是解决方案。

(2) 接下来我尝试的是从我的原始 .p12 证书中提取私钥和证书作为纯文本 (.pem) 文件,以便尝试创建一个新的 .jks 文件。所以我设法将我的私钥和我的证书从原始 .p12 证书中提取为纯文本。然后使用 keytools 和 openssl 我尝试使用此处提到的原始数据创建新的 .jks 文件: How to Creat JKS KeyStore file from existing private key and certificate 好吧,它的工作方式是创建我的新 .jks 文件,但是 SHA1 密钥(再次...:F7)与原始密钥(...:E5)不同。

(3) 我的下一步是通过互联网阅读和查找更多内容。找到了一些解决方案,这些解决方案表明转换最后一次在 java 1.8.0_111 中工作,并且上面的每个 java 发行版都有同样的问题。所以,让我们安装 java 1.8.0_111 并试一试。当然,它没有用。问题保持不变。也在 java 1.10 和 Oracle 版本中尝试过,仍然无法正常工作

(4) 我做的最后一件事,我安装了 java 1.6 并尝试使用它,没有问题,它运行完美,我设法阅读了.p12 没有问题,将它转换为 .jks 没有任何问题,就像一个魅力。生成的 SHA1 密钥 (...:E5) 与原始密钥 (...:E5) 相同!!!

但是,问题是我需要使用该证书签名的应用程序是使用 java 1.8 开发的,而 java 1.8 无法读取该证书。所以在这一点上我很沮丧,因为我已经在这个问题上输了几天了。

所以,无法读取,无法重新生成,无法对应用程序签名...

所以我的问题是:是否可能,如果可能,如何使用 .p12 证书签署 Android apk?

我不确定这个问题有多普遍,但欢迎任何可能的帮助。

讨厌成为坏消息的传播者,但这是版本控制在企业环境中至关重要的原因之一。当事情更新时,构建可能会中断。

我想到了上面没有看到的三件事:

1] 如果您使用的是 IDE,例如 Android Studio 或 IntelliJ,您可以尝试将您的项目分解为 Java 1.8 代码和 Java 1.6 代码.例如,您可以创建一个密钥库签名模块,然后添加 gradle 命令以使用 Java 1.6 构建它,而您的项目模块的其余部分使用 Java 1.8 构建。

2] 您可以尝试创建自己的签名 class,并直接调用 Java 1.6 classes,您可以将其手动添加到您的项目中。

3] 您可以使用新的密钥库,更改您的程序包名称,并将您以前的商品详情指向新的 Java 1.8 应用程序。这可能是最不受欢迎的,因为它会被视为商店中的新应用。

我终于找到了解决我面临的这个问题的最佳方法。实际上解决方案就在我面前,只需付出一点点努力。

我尝试切换到 java 1.6 版本只是为了对应用程序进行签名,实际上我确实设法进行了签名。之后我会再次将应用程序转移到 1.8 java 环境并成功完成 zipalign!当我完成所有这些时,我真的很高兴,希望 Google Play 最终接受 apk。 我将 apk 上传到商店后,我的希望就破灭了。 Google Play 说并非所有文件都已签名,我需要上传所有已签名文件的 apk。你能想象沮丧的程度吗?

我的问题是我有旧的 .p12 证书,无法在 AndroidStudio 中读取或转换为 jks,但我能够从该文件中提取我的私钥和我的证书。

在我试着多看看周围之后,我设法找到了 apksigner tool 的解决方案。

实际上我所做的是,我构建了一个用调试密钥签名的 .apk,然后使用 apksigner 工具,提供了我的私钥和证书文件,最后对 apk 进行了签名。然后我就可以毫无问题地将 apk 上传到 Google Play 商店。

我用apksigner工具对apk进行签名的命令是:

./apksigner sign --key <your_private_key_in_.pcks8> --cert <your_certificate_in.der> <your_debug_signed_application_in.apk>

这里需要注意的是你的密钥必须是.pcks8格式,否则命令将无法运行。此外,apksigner 是 运行 作为 linux 上的脚本,这就是为什么在 apksigner 之前使用“./”。如果您在 windows 上安装了此工具或以其他方式安装,您应该可以使用 apksigner.exe 或 apksigner 启动命令。

如果您的密钥是纯文本 (.pem) 格式,可以使用 openssl 命令将其转换为 .pcks8 格式:

openssl pkcs8 -topk8 -inform PEM -outform DER -in <your_private_key_in.pem> -out <your_private_key_in.pcks8> -nocrypt

我们无法使用合法证书签署我们的应用程序。因此,我们改为使用自制证书来编译/发布应用程序。然后我们使用微软的 Signtool(.exe) 来完成这项工作。工作得很好。