我知道,关于这个问题有很多不同的问题和很多答案...但我无法理解......
我有:ubuntu-9.10-desktop-amd64 NetBeans6.7.1从“关闭”按“原样”安装 . 代表 . 我需要通过HTTPS连接到某个站点 . 为此我使用Apache的HttpClient .
从教程我读到:
“一旦正确安装了JSSE,通过SSL进行的安全HTTP通信就应该如此
简单的HTTP通信 . “还有一些例子:
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}
到现在为止,我写道:
HttpClient client = new HttpClient();
HttpMethod get = new GetMethod("https://mms.nw.ru");
//get.setDoAuthentication(true);
try {
int status = client.executeMethod(get);
System.out.println(status);
BufferedInputStream is = new BufferedInputStream(get.getResponseBodyAsStream());
int r=0;byte[] buf = new byte[10];
while((r = is.read(buf)) > 0) {
System.out.write(buf,0,r);
}
} catch(Exception ex) {
ex.printStackTrace();
}
结果我有一组错误:
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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1627)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:204)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:198)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:994)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:142)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:533)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:471)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:904)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1132)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:643)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at simpleapachehttp.Main.main(Main.java:41)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:302)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:205)
at sun.security.validator.Validator.validate(Validator.java:235)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:973)
... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:191)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:297)
... 23 more
我该怎么做才能创建最简单的SSL连接? (可能没有KeyManager和信任经理等 . )
18 回答
一旦你有了一个Java Cert Store(通过使用上面创建的优秀的InstallCert类),你可以通过在java启动时传递"javax.net.ssl.trustStore" param来让java使用它 .
例如:
https://mms.nw.ru使用自签名证书,该证书显然不包含在默认的信任管理器集中 .
您需要执行以下操作之一:
使用接受任何证书的TrustManager配置SSLContext(参见下文)
使用包含证书的相应信任存储配置SSLContext
将该站点的证书添加到默认的Java信任库 .
这是一个示例程序,它创建一个(几乎毫无 Value 的)SSL上下文,它接受任何证书:
https://mms.nw.ru可能使用非认证机构颁发的证书 . 因此,您需要将证书添加到受信任的Java密钥存储区,如unable to find valid certification path to requested target中所述:
除了Pascal Thivent的正确答案之外,另一种方法是从Firefox(查看证书 - >详细信息 - >导出)或
openssl s_client
保存证书并将其导入信任库 .只有在有办法验证证书时才应该这样做 . 如果失败了,在第一次连接时执行此操作,如果证书在后续连接中意外更改,则至少会给您一个错误 .
要在信任库中导入它,请使用:
默认情况下,默认信任库应为
lib/security/cacerts
,其密码应为changeit
,有关详细信息,请参阅JSSE Reference guide .如果你没有't want to allow that certificate globally, but only for these connections, it'可以为它创建一个
SSLContext
:然后,您需要为Apache HTTP Client 3.x设置它,如果它的SecureProtocolSocketFactory使用此
SSLContext
,则执行一个 . (有例子here) .Apache HTTP Client 4.x(除了最早的版本)直接支持传递
SSLContext
.来自http://hc.apache.org/httpclient-3.x/sslguide.html:
哪里可以找到MySSLSocketFactory示例here . 它引用了
TrustManager
,您可以修改它以信任所有内容(尽管您必须考虑这一点!)Apache HttpClient 4.5方式:
注意:
org.apache.http.conn.ssl.SSLContextBuilder
是 deprecated ,org.apache.http.ssl.SSLContextBuilder
是新的(注意后者的包名中缺少conn
) .对于Apache HttpClient 4.5和Java8:
But if your HttpClient use a ConnectionManager for seeking connection, e.g. like this:
The HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory) has no effect ,问题没有解决 .
因为HttpClient使用指定的connectionManager来寻求连接,并且指定的connectionManager没有注册我们的自定义SSLConnectionSocketFactory . 要解决此问题,应在connectionManager中注册自定义的SSLConnectionSocketFactory . 正确的代码应该是这样的:
您可能遇到的自签名测试证书的另一个问题是:
java.io.IOException:HTTPS主机名错误:应该是......
当您尝试访问HTTPS网址时会发生此错误 . 您可能已经将服务器证书安装到JRE的密钥库中 . 但是,此错误意味着服务器证书的名称与URL中提到的服务器的实际域名不匹配 . 当您使用非CA颁发的证书时,通常会发生这种情况 .
此示例显示如何编写忽略证书服务器名称的HttpsURLConnection DefaultHostnameVerifier:
http://www.java-samples.com/showtutorial.php?tutorialid=211
有关在运行时轻松添加您信任的主机而不丢弃所有检查的方法,请尝试以下代码:http://code.google.com/p/self-signed-cert-trust-manager/ .
EasySSLProtocolSocketFactory给了我问题所以我最终实现了自己的ProtocolSocketFactory .
首先你需要注册它:
然后实现ProtocolSocketFactory:
注意:这是使用HttpClient 3.1和Java 8
想在这里粘贴答案:
在Apache HttpClient 4.5.5中
How to handle invalid SSL certificate with Apache client 4.5.5?
这link解释了您一步一步的要求 . 如果您不关心哪个证书可以继续下面的链接进程 .
注意您可能想要仔细检查自己正在做什么,这是一个不安全的操作 .
使用
InstallCert
生成jssecacerts
文件并且-Djavax.net.ssl.trustStore=/path/to/jssecacerts
工作得很好 .我正在使用httpclient 3.1.X,这对我有用
}
}
对于HttpClient,我们可以这样做:
按照下面给出的Java 1.7的说明,使用InstallCert.java程序文件创建SSL证书 .
https://github.com/escline/InstallCert
你必须重新启动tomcat
将以下内容与DefaultTrustManager一起使用,它在httpclient中工作,如charm . 万分感谢!! @Kevin和其他所有贡献者
我碰巧遇到了同样的问题,突然间我的所有进口都丢失了 . 我尝试删除.m2文件夹中的所有内容 . 并尝试重新导入所有内容,但仍然无效 . 最后,我所做的是打开了IDE抱怨它无法在我的浏览器中下载的网站 . 并看到它正在使用的证书,并在我看到
我的密钥库的路径是/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts
那个特定的证书不存在 .
因此,您所要做的就是再次将证书放入JAVA JVM密钥库 . 可以使用以下命令完成 .
如果要求输入密码,请尝试使用默认密码'changeit'如果在运行上述命令时出现权限错误 . 在Windows中以管理模式打开它 . 在mac和unix中使用sudo .
成功添加密钥后,您可以使用以下方法查看密钥:
您可以使用teh命令查看SHA-1