jarsigner:这个jar包含证书链没有被validation的条目

我想代码签署一个JAR文件,并使用JDK 1.7u1。 我们获得了GoDaddy代码签名证书,并按照说明操作(方法1): http : //help.godaddy.com/article/4780

JAR签名很好,但是每当我尝试运行命令时: jarsigner -verify使用JDK 1.7u1签署的JAR我得到以下输出:

 s 180 Mon Dec 05 10:24:32 EST 2011 META-INF/MANIFEST.MF [entry was signed on 12/5/11 10:24 AM] X.509, CN=Removed Company Name, O=Removed Company Name, L=Removed City, ST=Removed State, C=US [certificate is valid from 12/2/11 4:30 PM to 12/2/13 4:30 PM] X.509, SERIALNUMBER=00000000, CN=Go Daddy Secure Certification Authority, OU=http://certificates.godaddy.com/repository, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US [certificate is valid from 11/15/06 8:54 PM to 11/15/26 8:54 PM] X.509, OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US [certificate is valid from 6/29/04 1:06 PM to 6/29/34 1:06 PM] [CertPath not validated: null] 342 Mon Dec 05 10:24:34 EST 2011 META-INF/JAVACSC.SF 6180 Mon Dec 05 10:24:34 EST 2011 META-INF/JAVACSC.RSA 0 Mon Dec 05 10:24:30 EST 2011 META-INF/ sm 2161 Wed Nov 30 10:23:20 EST 2011 C:/Users/Seth/Desktop/JAR/RunAppSF.class [entry was signed on 12/5/11 10:24 AM] X.509, CN=Removed Company Name, O=Removed Company Name, L=Removed City, ST=Removed State, C=US [certificate is valid from 12/2/11 4:30 PM to 12/2/13 4:30 PM] X.509, SERIALNUMBER=00000000, CN=Go Daddy Secure Certification Authority, OU=http://certificates.godaddy.com/repository, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US [certificate is valid from 11/15/06 8:54 PM to 11/15/26 8:54 PM] X.509, OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US [certificate is valid from 6/29/04 1:06 PM to 6/29/34 1:06 PM] [CertPath not validated: null] s = signature was verified m = entry is listed in manifest k = at least one certificate was found in keystore i = at least one certificate was found in identity scope jar verified. Warning: This jar contains entries whose certificate chain is not validated. 

我也尝试了jarsigner -verify命令,在JDK 1.6u26和1.6u14上使用与上面相同的JAR,并且返回正常。 (输出低于1.6u26)。

  180 Mon Dec 05 10:24:32 EST 2011 META-INF/MANIFEST.MF 342 Mon Dec 05 10:24:34 EST 2011 META-INF/JAVACSC.SF 6180 Mon Dec 05 10:24:34 EST 2011 META-INF/JAVACSC.RSA 0 Mon Dec 05 10:24:30 EST 2011 META-INF/ sm 2161 Wed Nov 30 10:23:20 EST 2011 C:/Users/Seth/Desktop/JAR/RunAppSF.class [entry was signed on 12/5/11 10:24 AM] X.509, CN=Removed Company Name, O=Removed Company Name, L=Removed City, ST=Removed State, C=US [certificate is valid from 12/2/11 4:30 PM to 12/2/13 4:30 PM] X.509, SERIALNUMBER=00000000, CN=Go Daddy Secure Certification Authority, OU=http://certificates.godaddy.com/repository, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US [certificate is valid from 11/15/06 8:54 PM to 11/15/26 8:54 PM] [KeyUsage extension does not support code signing] X.509, OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US [certificate is valid from 6/29/04 1:06 PM to 6/29/34 1:06 PM] s = signature was verified m = entry is listed in manifest k = at least one certificate was found in keystore i = at least one certificate was found in identity scope jar verified. 

我错过了一个额外的步骤,我需要采取适当的JAR签署JDK 1.7?

不会错过任何东西,而且绝对不是这个问题。 经过近12个小时的斗争之后,我发现问题的根源在于将JDK 1.7二进制文件与旧版本的Java(如JRE-1.6混合在一起。 更确切地说, keytool附带了JRE ,而JDK附带了keytooljarsigner

所以,为了解决这个问题,我从系统中完全卸载了JDK-1.7并安装了JDK-1.6 Update 30 。 现在,如果我会做jarsigner -verify -verbose -certs blah.jar它会产生jar verified没有任何警告,我相信是你所期望的。

我一直有同样的问题,如果它可以帮助别人的问题是如何jarsignerfind密钥存储。

为了解决这个问题:

 jarsigner -verify -keystore xxxx.jks mysignedjar.jar 

这只是一个你可以忽略的警告。

如果你真的不想忽略它,那么在你validation时告诉jarsigner你的密钥库在哪里。

 jarsigner -verbose -verify -keystore ${KEYSTORE_PATH} ${YOUR_JAR_FILE} 

这只是JDK 7中的一个新function。

我与“DigiCert SHA2 Assured ID Code Signing CA”有类似的问题。 所有oracle java版本以及OpenJDK的performance都一样。 Digicert支持redirect我到这个页面,但是这里没有任何说明帮助我在validation过程中。

我试图签署一个applet,所以我需要在浏览器中validation它,所以提供keystorepath到jarsigner -verify的技巧是不适用的。

主要问题似乎是在使用SHA2而不是SHA1使用证书操作时,keytool中的一个错误,因为在SHA1证书上应用的相同步骤列表总是有效,并且从来没有为我工作过。 在我看来,keytool无法检测导入到jks的证书的“可链接性”,因此jarsigner没有将正确的证书链embedded签名的jar中,只有最后的证书存储在META-INF / myalias中。 RSA文件(可通过openssl pkcs7 -in myalias.RSA -print_certs -inform DER -out certs.crt进行validation)。

Digicertbuild议“ …我们有时会发现Root根本没有被正确导入或第一次完全导入,但是再次运行一个指向Root的导入命令可以解决这个问题 ”,即使这样做对我来说也没有帮助。

由于没有办法明确地说keytool哪些证书即将在一个链中,我决定使用openssl构build一个链,并像这样导入它:

 cat TrustedRoot.pem DigiCertCA2.pem my.crt >chain openssl pkcs12 -nodes -export -in my.crt -inkey my.key -out tmp.p12 -name myalias -certfile chain keytool -importkeystore -destkeystore mykeystore.jks -srckeystore tmp.p12 -srcstoretype PKCS12 

在此之后,mykeystore.jks似乎只包含我的证书,而不是通过keytool -list命令列出的DigiCertCA2或Root,但使用-v(详细)时,它会公开链深度及其证书:

 ~/$ keytool --list --keystore mykeystore.jks -v|grep -e chain -e Certificate\\[ Enter keystore password: 123456 Certificate chain length: 3 Certificate[1]: Certificate[2]: Certificate[3]: 

这就是jarsigned需要正确签名的jar文件,即为最终的浏览器用户提供正确的证书链和jar文件。

如果使用JRE 1.7.0_21对Jar文件进行签名并使用较低版本的JRE 1.7.0进行validation,则会发现消息“This jar contains entries of certificates chain not validated”也会打印出来。

结论:无需降级到Java 1.6,只需使用相同的jarsigner版本进行签名和validation即可。

这是JDK 7+中的一个安全机制。 这会在签名没有时间戳的jar子时打印警告,这可以通过-tsa标志来传递。 如果一个jar子没有时间戳记,它将停止工作超过其有效期。

如果您正在构buildAndroid目标,那么如果您使用的是比1.7.0_51更新的JDK,则会始终打印此警告。 Android一般build议通过30年的有效期,所以这个警告可以被100%忽略,除非你的商业计划是允许用户在2046年使用相同的.apk。

这里是function的票,目的是鼓励时间戳,我相信这将是有效的。 http://bugs.java.com/view_bug.do?bug_id=8023338

如果您的证书来自Entrust,请确保您使用的是较新的根证书。

http://www.entrust.net/knowledge-base/technote.cfm?tn=7875

问题:

您会收到一条错误消息,指出您的SLL证书validation由于缺lessBasic Constraints字段而失败。

解:

在2009年,Entrust重新发布了2048位根证书,其中包括基本约束字段(CN = Entrust.net Certification Authority(2048),有效期为7/24/2029)。 Entrust已经停止通过Windows和Java的根更新(从版本1.6更新22开始)推出原来的2048位root。 包含基本约束的更新的根证书可以在这里find:

https://www.entrust.net/downloads/binary/entrust_2048_ca.cer

当您创build/导出您的证书到p12(由jarsigner使用)时,确保您确保select了以下内容(例如,如果使用Internet Explorer向导导出),您将需要在导出向导中select以下内容。

“导出私钥”“在可能的情况下包含证书path中的所有证书”“在选项.PFX或PKCS#12下选中”导出所有扩展属性“。

如果您首先正确创build了p12,那么jarsign不需要特别的努力。