我有一个奇怪的问题(它是100%的服务器配置问题),例如我想从Dropbox下载一些东西:
解析dl.dropboxusercontent.com ... 23.23.160.146,50.17.227.107, 54.221.248.69,...连接到dl.dropboxusercontent.com | 23.23.160.146 |:443 ...已连接。错误: 无法验证由dl.dropboxusercontent.com颁发的证书 “/ C = US / ST = CA / O = SonicWALL Inc./CN=SonicWALL防火墙DPI-SSL”:
遇到自签名证书。连接到 dl.dropboxusercontent.com不安全,请使用'--no-check-certificate'。
是的,我知道我可以使用--non-check-certificate但是当我想在Java应用程序中使用SSL连接时,我有类似的东西:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:PKIX路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException:无法 找到所请求目标的有效证书路径
此应用程序在其他服务器或本地计算机中运行良好,任何想法在这里有什么问题?
答案 0 :(得分:3)
/ C = US / ST = CA / O = SonicWALL Inc./CN=SonicWALL防火墙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的cacerts
目录中的lib/security
文件的副本。您也可以直接在cacerts
文件上执行此操作(使用-keystore /path/to/truststore.jks
,前提是您具有写入权限。)
如果您选择不在默认信任库(cacerts
文件)上执行此操作但使用truststore.jks
之类的本地信任库,则可以在运行应用程序时使用此系统属性来使用它:-Djavax.net.trustStore=/path/to/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列表中的任何其他证书共享其“友好名称”,您应该没问题。
答案 1 :(得分:1)
您需要在客户端的Java密钥库中添加服务器的SSL证书。看一下这篇SO帖子:
提示:这是因为您客户的JVM不信任'服务器的SSL证书。因此,您需要在密钥库中添加证书。