关于keytool:jarsigner -verify在Java 6中有效,但在Java 7中无效

jarsigner -verify works in Java 6 but not Java 7

我已经为此奋斗了几天,完全陷入了困境。以下是摘要:

  • 我有一个使用Tycho通过Maven 3构建的Eclipse插件项目
  • 在Maven中,我已经设置了maven-jarsigner-plugin以使用我的密钥库对jar进行签名(有关密钥库的详细信息,请参见下文)
  • 我有一个Thawte在我的密钥库中签名的代码签名证书
  • 我可以从target / *获取任何签名的jar文件,然后在其上运行'jarsigner -verify'。这是发生了什么:

    1
    2
    3
    #java 6 on a VM
    vagrant@test2:/vagrant/com.example.plugins.eclipse/target$ jarsigner -verify com.example.eclipse-0.1.3-SNAPSHOT.jar
    jar verified.

    下一个:

    1
    2
    3
    4
    5
    6
    7
    8
    #java 7 on a completely different vm
    vagrant@test1:/vagrant$ jarsigner -verify com.example.eclipse-0.1.3-SNAPSHOT.jar
    jar verified.

    Warning:
    This jar contains entries whose certificate chain is not validated.

    Re-run with the -verbose and -certs options for more details.

    我注意不要使用同时安装了Java6和Java7的计算机,所以这不是问题

    我也不相信它是基于算法的(如本期所述),因为我可以使用Java 6或Java 7对项目进行签名,并且无论我在哪个环境下对jar进行签名,它都始终在Java6中进行验证,而从未在Java7中进行验证。 。

    这是keytool -list的输出

    1
    2
    3
    4
    5
    6
    7
    8
    Keystore type: JKS
    Keystore provider: SUN

    Your keystore contains 3 entries

    root, Aug 11, 2013, trustedCertEntry,
    Certificate fingerprint (SHA1): 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81
    intermediate, Aug 11, 2013, trustedCertEntry,

    我必须相信这是证书链问题,因为我能够在Java 7上使用以下命令来验证jar:

    1
    jarsigner -verify -keystore keystore com.example.eclipse-0.1.3-SNAPSHOT.jar

    显然,不能让我的插件的每个用户都使用我的密钥库文件,所以这不是解决方案。但是,这确实加强了我在Java 7中存在证书链的问题。


    问题的答案是,您正在使用SUN作为密钥存储库提供程序,因此在Oracle购买SUN之前发布了Java 6,并在之后购买了Java 7,并且不推荐使用许多Sun软件包。您可以在这里验证。

    Oracle保留了对不推荐使用的SUN密钥库提供程序的支持,但现在要求发出警告,就像您使用任何不推荐使用的功能一样。

    Oracle撰写了很长的详细说明,以说明为什么不应该在其网站上的JCA文档中使用SUN提供程序进行安全签名。

    唯一可以"解决"此问题的方法是将您的密钥库提供程序更改为oracle可接受的,您可以在上面链接的同一安全文档中找到它们。

    希望能有所帮助。


    确实有效。在两种情况下,您都将得到" jar验证" =>在两种情况下,JAR都将得到验证。这意味着JAR已由声称要签名的人签名,并且JAR随后未被篡改。

    Java 7正在打印警告。


    几个月后,我碰巧想出了我自己问题的答案。对于其他遇到相同问题的人,这是我的工作:

  • 将您现有的私钥和CA签名证书转换为pkcs12格式(这是必需的,因为Java的keytool不允许直接导入这些项目)。这可以通过单个openssl命令完成:

    1
    openssl pkcs12 -export -name signing -in signing.cert -inkey myPrivateKey.key -out keystore.p12

    其中signing是我的pkcs12密钥库的名称,signing.cert是我的CA提供的已签名证书,(显然)myPrivateKey.key是用于签署证书请求的私钥。

  • 将此新创建的密钥库导入到Java密钥库中:

    1
    keytool -importkeystore -destkeystore keystore -srckeystore keystore.p12 -srcstoretype pkcs12 -alias signing
  • 将您的CA的Java证书导入密钥库。我不确定这有什么魔力,但是没有它,证书链就不会被遵循(即使手动添加中间证书也是如此)。通常通过您的签名证书到达的电子邮件来提供此证书。就我们的目的而言,它称为signing.pkcs7。

    1
    keytool -importcert -file signing.pkcs7 -keystore keystore -v -alias signing

    您必须输入创建Java密钥库时使用的密钥库密码。

  • 在构建过程中,使用maven-jarsigner-plugin(或所需的任何自动化方法)对项目进行签名。