在Java中请求URL时忽略证书错误
我正在尝试打印一个URL(根本没有涉及浏览器),但URL目前正在抛出以下内容:
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
我使用JEditorPane的setPage方法调用URL,该方法仅将URL作为参数。 假设我无法更改任何服务器端,我仍然需要访问此资源,我将如何忽略证书错误(或其他让我达到目标的东西)?
通过浏览器访问此URL告诉我该网站不受信任,并询问我是否要继续。
扩展JEditorPane
以覆盖getStream()
方法。
在该方法中,您可以打开URLConnection
。 测试它是否是HttpsURLConnection
。 如果是,请使用不执行任何检查的自定义X509TrustManager
初始化您自己的SSLContext
。 获取上下文的SSLSocketFactory
并将其设置为连接的套接字工厂 。 然后从连接返回InputStream
。
这将破坏运行时保护用户免受恶意软件欺骗站点攻击的任何尝试。 如果这真的是你想要的……
这可能是因为您的密钥库中用于访问目标HTTPS
URL的证书与来自服务器的证书不匹配。
您需要将证书导入JVM的密钥库。 获取密钥库证书以访问此URL,然后使用导入到主密钥库
keytool -importkeystore -srckeystore /path/to/custom/keystore -destkeystore $JAVA_HOME/jre/lib/security/cacerts
假设您使用的是$JAVA_HOME
Java
我会用erickson解决方案。
另一种方法是将服务器的证书(可能是自签名的)添加到您的可信证书KeyStore(我会在您的测试环境中进行)。
使用:
java InstallCert YourHost
创建一个jssecacerts文件,然后将其复制到以下文件夹:
$JAVA_HOME/jre/lib/security
如果它与您每次都要联系的服务器相同,则可以通过将其添加到信任存储区来简单地信任该证书。 我不会将其添加到默认的cacerts文件中,但您可以创建自己的密钥库并通过javax.net.ssl.trustStore系统属性指定它。
最后,如果你想完全禁用PKIX检查(只有当你明白这会危及安全性时才会这样做),唯一的办法就是像erickson所建议的那样实现你自己的SSL上下文和信任管理器。
在相关的说明:我与WCF .net Web服务的相互认证身份validation导致我的测试环境出现问题。 我将这两行添加到我的代码中以解决问题并允许我解决问题:
//Uncomment this in case server demands some unsafe operations System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true"); //this command allowed me to see the detailed debugger log for detecting the //issue with my certs. System.setProperty("javax.net.debug","all");
以下是在Java / Windows / Unix世界中处理SSL协商和证书的好参考: 传输层安全性(TLS)重新协商问题自述文件