2014-07-24 191 views
2

我有一个奇怪的问题(这是100%的服务器的配置问题)比如我想从Dropbox的下载东西:Debian的SSL证书错误:无法验证XXX证书/ javax.net.ssl.SSLHandshakeException

Resolving dl.dropboxusercontent.com... 23.23.160.146, 50.17.227.107, 54.221.248.69, ... Connecting to dl.dropboxusercontent.com|23.23.160.146|:443... connected. ERROR: cannot verify dl.dropboxusercontent.com’s certificate, issued by “/C=US/ST=CA/O=SonicWALL Inc./CN=SonicWALL Firewall DPI-SSL”:
Self-signed certificate encountered. To connect to dl.dropboxusercontent.com insecurely, use ‘--no-check-certificate’.

是的,我知道,我可以使用--non检查证书,但是当我想用在Java应用程序的SSL连接我有这样的事情:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这个应用在其他的服务器或本地的伟大工程机器,有什么想法这里有什么不对?

回答

1

您需要在客户端的Java密钥库中添加服务器的SSL证书。在此SO后看看:

Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?

提示:这是因为你的客户端的JVM不“信任”服务器的SSL证书。所以你需要在你的密钥库中添加证书。

+0

有没有可能“信任”每个网页? – user3771297

+1

@ user3771297如果您信任所有证书,将会取消证书的整个概念:)但是,您可能想看看这个http://stackoverflow.com/questions/2893819/telling-java-to-accept -self-signed-ssl-certificate我建议宁可使用你提到的“--no-check-certificate”选项。但是,你确定吗? – Pat

+0

@ user3771297有许多方法可以禁用证书验证,但它们是99.9999999%的时间的可怕想法。它感觉*就像是一种快速的方式,但之后会导致更多的麻烦:您必须在代码投入生产之前将其删除,否则您会忘记并在应用程序中留下安全漏洞(请记住,您在没有解决问题的情况下关闭“警报”,在发布之前很可能不会注意到)。这两种都不是好选择。 – Bruno

3

/C=US/ST=CA/O=SonicWALL Inc./CN=SonicWALL Firewall DPI-SSL

您的流量被深层数据包检测防火墙截获,该防火墙充当MITM代理来监控您的流量。

这通常可以被认为是“合法”的MITM攻击者。 (然而,合法的这可能取决于一些法律和道德方面。)您的本地网络管理员应该能够告诉您一些关于此的信息。如果这是公司网络的一部分,则该公司正在监控您的流量,包括您的HTTPS连接的内容(因此它不再安全,不受端到端的限制)。它防火墙的工作正常,它仍然应该保证从防火墙到服务器的连接(很可能很难知道它是否正确地检查证书)。

一般来说,这样的防火墙或代理可以作为自己的认证授权,按要求有效伪造每个证书。

企业网络上的大多数客户会相信它的问题(如一个你面对)证书,因为系统管理员也将安装CA证书作为网络中的受信任的证书到每台机器。您可能拥有操作系统受信任的根证书。

但是,网络管理员很可能没有将此CA证书安装到您的JRE安装(默认使用其自己的一组信任锚)。

尝试从参考机器导出该CA证书(请参阅上面的名称),并将其导入到您正在使用的信任库(您的JRE默认信任库:cacerts或您构建的新信任库并通过您的应用程序javax.net.trustStore属性)。

通常情况下,你可以使用这样的事情(假设你已经出口防火墙的CA为“firewallca.pem”):

keytool -import -file firewallca.pem -alias firewallca -keystore truststore.jks 

如果truststore.jks文件不存在,它将被创建。否则,您可以在JRE的lib/security目录中获取cacerts文件的副本。你也可以这样做直接在cacerts文件(使用-keystore /path/to/truststore.jks,前提是你必须把它写访问)。-Djavax.net.trustStore=/path/to/truststore.jks

为:

如果您选择不去做的默认信任(即cacerts文件),但使用的是本地信任像truststore.jks,你就可以使用此系统属性运行应用程序时使用它其他配置信任库的方法,请检查this answer


解决此问题的另一种方法是告诉Java使用your OS's truststore。我假设你在这里使用Windows。使用这些系统属性应该工作:

-Djavax.net.trustStore=NONE -Djavax.net.trustStoreType=WINDOWS-ROOT 

(与WINDOWS-MY而不是WINDOWS-ROOT尝试,如果这行不通。)

WINDOWS-MY/WINDOWS-ROOT是有点马车,它将会错过一些证书在Windows商店中:它使用证书“友好名称”(非唯一)作为密钥库别名(唯一),因此具有给定友好名称的证书将隐藏具有相同名称的证书。 (这有效地减少了可信赖的CA证书的数量。)

由于您处于大概所有流量均通过DPI防火墙的环境中,因此您可能只需使用一个CA证书即可最。只要它不与其他任何证书共享Windows列表中的“友好名称”,就应该没问题。

+0

“这通常可以被认为是'合法'的MITM攻击者” - 不存在合法攻击这样的事情。它就像说你可以得到一半的preganant。 (1)Dropbox是否同意被拦截(可能不是)。 (2)你如何教程序员区分“好”坏人“和”坏“坏人(你不能)? – jww

+1

@jww我并不反对,但它可以让公司检查所有人它的SSL流量,并不是关于Dropbox被拦截,而是关于公司监控其网络。 – Bruno