【问题标题】:Sign Android Native apk with Adobe Air certificate使用 Adob​​e Air 证书签署 Android Native apk
【发布时间】:2018-12-17 10:54:24
【问题描述】:

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

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?

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

【问题讨论】:

    标签: java android ssl air certificate


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 您的第一个建议是我没有想到的,谢谢。我会尝试这个和更多的东西,如果我成功了,我会写一个答案我是怎么做到的。
    • 我写了对我有用的解决方案,你可以看看。谢谢你的想法;)
    【解决方案2】:

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

    我尝试切换到 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 命令将其转换为 .pcs8 格式:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2019-04-21
        • 1970-01-01
        • 2017-11-17
        • 2016-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多