在 Java 中请求 URL 时忽略证书错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2694281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ignore certificate errors when requesting a URL in Java
提问by Ryan Elkins
I'm trying to print a URL (without having a browser involved at all) but the URL is currently throwing the following:
我正在尝试打印一个 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
I'm calling the URL using a JEditorPane's setPage method, which just takes a URL as a parameter. Assuming I can't change anything server side and I still need to get to this resource, how would I go about ignoring the certificate error (or something else that gets me to my goal)?
我正在使用 JEditorPane 的 setPage 方法调用 URL,该方法仅将 URL 作为参数。假设我无法更改服务器端的任何内容并且我仍然需要访问此资源,我将如何忽略证书错误(或其他使我达到目标的东西)?
Accessing this URL via a browser tells me the site is untrusted and asks me if I want to proceed.
通过浏览器访问此 URL 会告诉我该站点不受信任,并询问我是否要继续。
回答by erickson
Extend JEditorPaneto override the getStream()method.
扩展JEditorPane以覆盖该getStream()方法。
Inside that method, you can open a URLConnection.Test whether it is an HttpsURLConnection. If it is, initializeyour own SSLContextwith a custom X509TrustManagerthat doesn't perform any checks.Get the context's SSLSocketFactoryand set it as the socket factoryfor the connection. Then return the InputStreamfrom the connection.
在该方法中,您可以打开一个URLConnection. 测试它是否是HttpsURLConnection. 如果是,请使用不执行任何检查的自定义初始化您自己的SSLContext。获取上下文并将其设置为连接的套接字工厂。然后从连接返回。X509TrustManagerSSLSocketFactoryInputStream
This will defeat any attempts by the runtime to protect the user from a spoof site serving up malware. If that's reallywhat you want…
这将阻止运行时保护用户免受提供恶意软件的欺骗站点的任何尝试。如果这真的是你想要的……
回答by ring bearer
This is possibly because your certificate in your keystore for accessing target HTTPSURL does not match the certificate from server.
这可能是因为您的密钥库中用于访问目标HTTPSURL 的证书与来自服务器的证书不匹配。
You need to import the certificate in to your JVM's keystore. Obtain keystore certificatesto access this URL and then importit into the main keystore with
您需要将证书导入到 JVM 的密钥库中。获取密钥库证书以访问此 URL,然后使用以下命令将其导入主密钥库
keytool -importkeystore -srckeystore /path/to/custom/keystore -destkeystore $JAVA_HOME/jre/lib/security/cacerts
keytool -importkeystore -srckeystore /path/to/custom/keystore -destkeystore $JAVA_HOME/jre/lib/security/cacerts
Assuming you are using Java from $JAVA_HOME
假设您使用的是 Java $JAVA_HOME
回答by systempuntoout
I would use erickson solution.
Another way is to add server's certificate (probably self signed) to your trusted certificates KeyStore (I would do it just in your test enviroment).
Use:
我会使用埃里克森解决方案。
另一种方法是将服务器的证书(可能是自签名)添加到您的受信任证书 KeyStore(我只会在您的测试环境中这样做)。
利用:
java InstallCert YourHost
to create a jssecacertsfile then copy it to the following folder:
创建一个jssecacerts文件,然后将其复制到以下文件夹:
$JAVA_HOME/jre/lib/security
回答by Nick
If it is the same server that you will be contacting each time, it might be okay to simply trust this one certificate by adding it to the trust store. I wouldn't add this to the default cacerts file, but you can make your own keystore and specify it through the javax.net.ssl.trustStore system property.
如果它是您每次将联系的同一台服务器,则可以通过将它添加到信任库来简单地信任这个证书。我不会将它添加到默认的 cacerts 文件中,但您可以创建自己的密钥库并通过 javax.net.ssl.trustStore 系统属性指定它。
Lastly, if you want to disable PKIX checking completely (which you should only do if you understand that this will compromise security quite a lot) the only way is to implement your own SSL context and trust manager as erickson has suggested.
最后,如果您想完全禁用 PKIX 检查(只有在您了解这会严重损害安全性时才应该这样做),唯一的方法是实现您自己的 SSL 上下文和信任管理器,正如 erickson 所建议的那样。
回答by Chad
On a related note: my mutual certifcate authentication with a WCF .net Web Service was causing issues in my test environment. I added these two lines to my code to fix the problem and allow me to work through the issue:
相关说明:我与 WCF .net Web 服务的相互证书身份验证在我的测试环境中引起了问题。我将这两行添加到我的代码中以解决问题并允许我解决问题:
//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");
Here is a nice reference for dealing with SSL negotiation and certifcates in a Java/Windows/Unix world: Transport Layer Security (TLS) Renegotiation Issue Readme
这是在 Java/Windows/Unix 世界中处理 SSL 协商和证书的不错参考:传输层安全性 (TLS) 重新协商问题自述文件

