由于要求,我们需要通过将系统日期转移到未来日期(如2025-05-05)来测试https连接,问题是当使用HttpClient
(版本4.2)时,会遇到异常
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
简单的代码段如下:
@Test
public void httpsShouldWorking() throws Exception {
HttpClient client = new DefaultHttpClient();
String urlOverHttps = "https://URL";
HttpGet getMethod = new HttpGet(urlOverHttps);
HttpResponse response = client.execute(getMethod);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
我也谷歌搜索并找到了解决方案HttpClient with SSL
如上所述:
现在让我们将http客户端配置为信任所有证书链,无论其有效性如何:
但是在尝试之后,它无法正常工作并仍然获得auth异常。
在转移系统日期时是否有避免身份验证的解决方案?
答案 0 :(得分:6)
可以使HttpClient绕过SSL证书有效性检查。此代码可用于获取HttpClient的实例:
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
......
private static HttpClient getHttpClient() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null,
new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
}}, new SecureRandom());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(socketFactory).build();
return httpClient;
} catch (Exception e) {
e.printStackTrace();
return HttpClientBuilder.create().build();
}
}
将不再抛出异常,当认证过期时,浏览器将发出有关过期证书的警告并让用户确认。
答案 1 :(得分:2)
public static HttpClient verifiedClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("SSL");
X509TrustManager tm = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager mgr = base.getConnectionManager();
SchemeRegistry registry = mgr.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
return new DefaultHttpClient(mgr, base.getParams());
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
答案 2 :(得分:2)
不是禁用整个安全链,而是将特定证书导入JAVA安装的密钥库更好。如何做到这一点,你可以在这里找到:http://java67.blogspot.co.at/2012/09/keytool-command-examples-java-add-view-certificate-ssl.html
答案 3 :(得分:1)
阅读了很多asnwers,this was the one that helped me。
我通过忽略一些TLS算法解决了我的问题。
修改档案:$JAVA_HOME/jre/lib/security/java.security
将这两个算法添加到DHE, ECDHE
列表中,将其添加到jdk.tls.disabledAlgorithms
列表中。
因此,在我的情况下,最终结果是:
jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE
答案 4 :(得分:0)
就我而言,在以下情况中:
以下参数有效:
-Djdk.tls.client.protocols=TLSv1
有关更多信息,请查看:
https://www.java.com/en/configure_crypto.html