GoDaddy SSL证书不适用于Java

UPDATE 1/26/2015 -- It appears the most recent JRE/JDK for Java 8 (update >= 31) and JRE/JDK for Java 7 now include the Godaddy G2 CA server in the default trust store. If possible, it's urged you upgrade your JRE/JDK to the latest Java 8 update to resolve this issue.

更新11/29/2014 – 这仍然是一个问题,Godaddy似乎不在乎,也不会做任何事情。 几个月前,Godaddy安全产品副总裁在这里发表了一篇博客文章,表示正在解决这个问题,并提供了一个临时的解决scheme,但是到目前为止,还没有任何改变。 需要注意的是,Godaddy的G2 CA服务器已经存在了至less5年,在那个时候,Godaddy没有采取适当的措施来解决这个已知的问题。 提供的解决方法就是这样一个解决scheme,而不是一个解决scheme。 第三方服务的用户无法控制服务器上的证书安装方式。

It seems users should avoid purchasing Godaddy SSL certs until they get serious about being a CA.

如果您倾向于打电话,以下是他们的SSL团队的联系信息:

GoDaddy SSL Team Support Number: 1-480-505-8852 -- Email: ra@godaddy.com

更新9/17/2014 – 这仍然是一个问题,Godaddy似乎不在乎也不会做任何事情。 到11月份,当Google弃用所有的SHA-1证书时,这将成为一个主要问题。 我强烈build议任何可以联系Godaddy的人,并在这里指出他们。

tl;dr; - final update with current solution/workaround at the bottom of this post (it is a GoDaddy problem and there is a workaround until they fix it)

我有一个邮件服务器,我试图从我的Java应用程序发送邮件。 我可以在端口25上成功发送,所以我知道代码的作品和所有,但25是不encryption的会话。 我需要在需要SSL证书的端口587上使用TLS。 我在GoDaddy G2 CA签署的服务器上有一个有效的SSL证书,并且已经存在了一段时间(没有问题)。

我的问题是,我得到着名的PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 587尝试连接和发送邮件时PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target错误消息。

从我对许多SO链接以及普通的google-fu的理解中,通常是在Java不相信证书或CA时引起的 – 这对于自签名证书是很常见的。 我已经使用了几个在线的SSL Cert检查器,以确保链是有效的,等等都显得是正常的…但是java不会自动使用证书。

我知道有一个从Sun的某个类文件,将下载和设置本地密钥库中的证书,所以Java将信任它…但这不仅对于将被部署到多个系统的应用程序是不切实际的,愚蠢的Godaddy签署的证书。

这是怎么回事? 我怎样才能让java使用服务器上的有效证书, 不必让java接受所有的证书?

编辑:我只是看着我的Windows Java控制面板(默认安装的JDK 7),果然,在Signer CAThe Go Daddy Group, Inc. Go Daddy Class 2 Certification AuthorityThe Go Daddy Group, Inc. Go Daddy Class 2 Certification Authority列出…所以什么给? 我的证书是Godaddy证书

UPDATE --

这里是从评论中推荐的openssl命令看到的证书链:

 ~]# openssl s_client -connect smtp.somecompany.com:587 -starttls smtp CONNECTED(00000003) depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2 verify error:num=19:self signed certificate in certificate chain verify return:0 --- Certificate chain 0 s:/OU=Domain Control Validated/CN=smtp.somecompany.com i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 3 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 --- 

看起来对我来说我认为…

UPDATE 2 --

好的,感谢@Bruno,我能够确定我的链条是搞砸了 – 我重新键入服务器,现在我的链条出现如下:

  ~]# openssl s_client -connect smtp.somecompany.com:587 -starttls smtp CONNECTED(00000003) depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2 verify error:num=19:self signed certificate in certificate chain verify return:0 --- Certificate chain 0 s:/OU=Domain Control Validated/CN=smtp.somecompany.com i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 --- 

看起来比以前更好 –Java仍然抛出与证书path相同的exception,等等。所以看起来,默认情况下,G2证书链在java 7的默认密钥库中是不可信的。

FINAL UPDATE FOR COMPLETENESS @ 1/14/2014

就像更新 – 这确实是一个GoDaddy问题(我已经与他们长时间的电子邮件支持)。 他们有2个CA服务器,一个叫做Class 2 CA ,另一个叫G2 CA 他们的Class 2 CA签署所有SHA-1证书,而G2 CA签署他们所有的SHA-2证书。 这就是问题的所在 – GoDaddy没有将他们的新的G2 CA服务器添加到默认的java truststore中 – 导致默认的java安装不信任它的权限,因此不相信你的链接证书。 直到GoDaddy将G2 CA服务器添加到默认信任库为止的解决方法是简单地使用SHA-1重新签名证书,以获得由Class 2 CA服务器签名的证书。 对于GoDaddy客户,更新是免费的,直到您的证书到期(显然)。

UPDATE 1/26/2015 -- It appears the most recent JRE/JDK for Java 8 (update >= 31) and JRE/JDK for Java 7 now include the Godaddy G2 CA server in the default trust store. If possible, it's urged you upgrade your JRE/JDK to the latest Java 8 update to resolve this issue.

更新11/29/2014 – 这仍然是一个问题,Godaddy似乎不在乎,也不会做任何事情。 几个月前,安全产品部门的Godaddy副总裁[here][1]发表了一篇博客文章[here][1] ,表示修复正在进行中,并提供了一个临时解决scheme,但是至今为止,没有任何改变。 需要注意的是,Godaddy的G2 CA服务器已经存在了至less5年,在那个时候,Godaddy没有采取适当的措施来解决这个已知的问题。 提供的解决方法就是这样一个解决scheme,而不是一个解决scheme。 第三方服务的用户无法控制服务器上的证书安装方式。

It seems users should avoid purchasing Godaddy SSL certs until they get serious about being a CA.

如果您倾向于打电话,以下是他们的SSL团队的联系信息:

GoDaddy SSL Team Support Number: 1-480-505-8852 -- Email: ra@godaddy.com

更新9/17/2014 – 这仍然是一个问题,Godaddy似乎不在乎也不会做任何事情。 到11月份,当Google弃用所有的SHA-1证书时,这将成为一个主要问题。 我强烈build议任何可以联系Godaddy的人,并在这里指出他们。

~~~~

我最初的post/问题是关于为什么我的连锁店不工作。 很明显,我有一个不好的设置(这很快就被来自@Bruno和其他人的build议修复了,谢谢)。 但是,当我的纠正链仍然没有与Java的工作,很明显,有一个更大的潜伏问题。 这花了一段时间,但问题实际上是与GoDaddy。

这实际上确实是一个GoDaddy的问题(​​我已经与他们长时间的支持电子邮件)。

他们有2个CA服务器,一个叫做Class 2 CA ,另一个叫G2 CA 他们的Class 2 CA签署所有SHA-1证书,而G2 CA签署他们所有的SHA-2证书。

这就是问题的所在 – GoDaddy没有将他们新的G2 CA服务器添加到默认的Java truststore/keystore – 导致默认的Java安装不信任它的权限,因此不信任您的链接证书。

直到GoDaddy将G2 CA服务器添加到缺省信任库/密钥库为止的解决方法是简单地使用SHA-1重新签名您的证书,以获得由Class 2 CA服务器签名的证书。 对于GoDaddy客户,更新是免费的,直到您的证书到期(显然)。

一旦您拥有由Class 2 CA服务器签署的SHA-1证书,您的信任链应该按预期工作,并且不需要导入和/或设置自定义信任库/密钥库。

为了使它正常工作,我不得不使用“较弱”的证书,并且通过电子邮件支持与GoDaddy的讨论表明,他们目前没有计划将G2 CA服务器添加到默认信任库/密钥库。 我想直到他们添加它,确保你得到一个SHA-1 Class 2 CA服务器签署的证书,如果你打算使用Java。

Fixer先生和Wayne Thayer先生的回答都是低估的,但实际上他们主张正确的解决方法。 事实上,Wayne Thayer带领GoDaddy的SSL业务,所以他可能知道。 您应该在证书链中安装“GoDaddy G1到G2 Cross”证书以及中间证书。

降级到SHA1并不是一个理想的select,因为它已被弃用,将来会带来更多的工作。 幸运的是,GoDaddy提供了一个解决这个问题的交叉证书。 他们发布了韦恩重复的指示,他们被埋在这里的评论中 。

我已经用SHA2证书亲自testing过这个解决scheme,并且运行良好。 与重新键入和降级到SHA1相比,这是一个非常优越的解决scheme。 当需要SHA2时,该选项将不可用,并且可能还有没有新证书的Java工具链。

根据GoDaddy的支持,截至2014年7月,最新版本的Java 8中包含了正确的根证书。2014年9月,GoDaddy的Wayne Thayer 还表示 ,该证书“计划在未来几个月内添加到Java ”。 我已经检查了从这里下载的用于Mac OS的Java 8中的cacerts文件,它确实包含SHA2根证书。

所以,而不是你的链看起来像这样:

  • Go爸爸根证书颁发机构 – G2:(SHA-2) – 散列47 BE AB C9 22 EA E8 0E 78 78 34 62 A7 9F 45 C2 54 FD E6 8B。 这是内置于某些系统(例如Chrome)的根证书。 SnakeDoc声称“它不是内置到Java,Windows CE,Microsoft Exchange和更多的平台”。
  • Go爸爸安全证书颁发机构 – G2:(SHA-2) – 散列27 AC 93 69 FA F2 52 07 BB 26 27 CE FA CC BE 4E F9 C3 19 B8
  • 您的SHA2证书

它应该是这样的:

  • 去爸爸第2级authentication机构:(SHA-1) – 散列27 96 BA E6 3F 18 01 E2 77 26 1B A0 D7 77 70 02 8F 20 EE E4。 这是大多数系统内置的旧的根证书,包括java。
  • Go Daddy Root证书颁发机构 – G2:(SHA-2) – Hash 34 0B 28 80 F4 46 FC C0 4E 59 ED 33 F5 2B 3D 08 D6 24 29 64.这就是所谓的“GoDaddy G1到G2交叉证书” 。
  • Go爸爸安全证书颁发机构 – G2:(SHA-2) – 散列27 AC 93 69 FA F2 52 07 BB 26 27 CE FA CC BE 4E F9 C3 19 B8
  • 您的SHA-2证书

另请参阅 – 我的博客文章总结了这个问题的解决办法。

要使Godaddy证书能够以SHA2方式在Java中工作,您需要在您的链中使用交叉证书,将G2(SHA2)根链接到G1(SHA1)根,直到Java决定更新其存储库。 交叉证书包可以在这里下载:

https://certs.godaddy.com/anonymous/repository.pki

GoDaddy证书包 – G2与交叉到G1,包括根

 [gd_bundle-g2-g1.crt][1] 

Fixer先生是对的。 在证书包文件中安装“GoDaddy G1到G2 Cross”证书以及中间证书。 这使得GoDaddy SHA-2证书可被任何识别SHA-1根(包括Java)的客户端所信任。 您可以从https://certs.godaddy.com/repository获取此文件。一旦安装完成,Java将从您的证书到“GoDaddy安全服务器证书(中级证书)”到“GoDaddy G1到G2交叉证书“到GoDaddy SHA-1根目录。 您也可以在我们的资源库中find一个包含交叉证书的包文件。 关于此选项的最后一个注意事项:即使您依赖SHA-1根目录,也不检查根证书上的签名,这与完整的SHA-2证书链一样安全。

在注释和openssl s_client -connect the.server.name:587 -starttls smtp的输出之后, openssl s_client -connect the.server.name:587 -starttls smtp

在证书链中,证书n应该由证书n + 1发布在证书列表中:证书颁发者(i)应该是证书n + 1的主体。

  0 s:/OU=Domain Control Validated/CN=smtp.somecompany.com i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 3 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2 i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 

在这里,证书0由证书1(罚款)颁发,证书1由证书2(罚款)颁发,证书2是自签名(也罚款,这是根CA)。

但是,证书2不是由证书3颁发的。证书3是错误的(可能与证书1相同)。 这可能会导致问题,因为这使得链条无效。

您至less应该从configuration中删除证书3。 另外,您也可以删除cert 2,因为拥有根CA是没有必要的(无论如何,这取决于客户端)。

听起来你的邮件服务器没有被Go Daddy Class 2 Certification Authority签名,但实际上是由其中一个中间authentication机构签署的。 你需要自己validation一下。 假设是这样的…

理论上,您的软件应该可以工作 – 因为中间证书是由第2类权限签署的,并且您在默认的JDK证书存储中拥有第2类权限。 但是,我发现它不起作用,除非您还将中间证书添加到您的证书存储区。 这里是一个博客文章的链接,描述了类似的经验:

http://drcs.ca/blog/adding-godaddy-intermediate-certificates-to-java-jdk/

以下是更多GoDaddy中级证书的直接链接: https : //certs.godaddy.com/anonymous/repository.pki

我不能build议您必须添加哪个证书 – 这取决于您的邮件服务器使用哪个CA.

[更新]

is there a way to do this programmically?

也许。 取决于你想做什么。 我已经使用java.security.KeyStore类来直接从Java代码直接自动更新私钥库,而不使用keytool 。 它在概念上很简单 – 从文件加载密钥库,读取新证书,将其添加到密钥库,然后将密钥库写出到新文件中。 然而,需要一段时间才能得到正确的信息,导入单个证书可能并不值得。

不过,尝试一下很有趣。 签出KeyStore JavaDoc并读取loadstoresetCertificateEntry方法。

在“Java控制面板”中,我只是将GD根证书添加到“安全站点CA”,并且在使用Java时不再有证书错误。 我添加的证书是: 去爸爸Class 2authentication机构根证书 – G2

Update - this "solution" is no longer valid (see my above accepted answer) - keeping this answer because it did help alleviate the problem so long as the side-effects are tolerable.

好的,我可能已经为我的案子find了解决办法。

 props.put("mail.smtp.ssl.trust", "smtp.somecompany.com"); 

我把这个添加到我的会话build设,现在它的工作。 这是一个解决办法,而不是一个解决scheme,因为我仍然不知道为什么我的Godaddy SSL证书不是默认值得信赖的…这不是一个自签名的证书。

任何人都可以随意join,因为我真的很想理解这个问题。

如果将de GoDady G2软件包导入到java keystore中,则可解决此问题:

 export JAVA_HOME=/usr/lib/jvm/java-8-oracle/ wget https://certs.godaddy.com/repository/gd_bundle-g2.crt $JAVA_HOME/bin/keytool -import -alias root -file ./gd_bundle-g2.crt -storepass changeit -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts 

如果您在发送邮件时正在使用以下属性,请对其进行注释。 这对我有用。 但是这可能会导致安全问题。

 props.put("mail.smtp.starttls.enable","true");