我正在尝试使用Java 6和HTMLUnit连接SSL站点https://link.bollore-logistics.com,我使用Bouncy Castle添加了更多支持的密码。但是,我仍然收到握手失败。由于生产限制,我无法升级Java版本。请帮忙
配置代码:
.column {
float:left;
}
.column.main {
width:70%;
min-height:1px;
}
.column.side {
width:20%;
min-height:1px;
}
.column.left {
width:10%;
background-color:012C40;
height:85%;
min-width:1px;
}
.column.right {
width:10%;
background-color:012C40;
height:85%;
float:right;
min-height:1px;
}
.postAd {
width:19%;
height:32%;
float:left;
background-color:DAEBF2;
text-align:center;
display:inline-block;
margin:.5%;
overflow: auto;
}
.postAd img {
width:80%;
height:80%;*/
}
<div class="column left">
</div>
<!--middle content-->
<div class="postAd">
<img src="images/Sunset.JPG" alt="sunset">
<p>Text here!</p>
</div>
<div class="postAd">
<img src="images/Sunset.JPG" alt="sunset">
<p>Text here!</p>
</div>
<div class="postAd">
<img src="images/Sunset.JPG" alt="sunset">
<p>Text here!</p>
</div>
<div class="postAd">
<img src="images/Sunset.JPG" alt="sunset">
<p>Text here!</p>
</div>
<div class="postAd">
</div>
<!--right side content-->
<div class="column right">
</div>
建立连接的代码(HTMLUnit):
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
if (Security.getProvider("BC") == null){
logger.info("Bouncy Castle provider is NOT available");
}
else{
logger.info("Bouncy Castle provider is available");
}
Provider provider = new BouncyCastleProvider();
Security.addProvider(provider);
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, new X509TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}}, new SecureRandom());
String[] scs = context.getSocketFactory().getSupportedCipherSuites();
Arrays.sort(scs);
for(String s : scs) {
System.out.println(s);
}
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
以下是错误日志:
WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getPage(url);
答案 0 :(得分:0)
我遇到了类似的问题(但在这种情况下没有使用HtmlUnit。我直接使用了org.apache.http.impl.client.CloseableHttpClient)。
接缝有问题,握手直到java 7 (在java 8中没有问题)。如果您尝试访问提供&#34; TLSv1.2&#34;您可能会收到您报告的错误。
如果在您的情况下安全性不是那么大的问题,您可以尝试强制使用TLSv1.1(只要您还没有切换到java 8)。 这应该是这样的:
WebClientOptions webClientOptions= new WebClientOptions();
webClientOptions.setSSLClientProtocols(new String[]{"TLSv1.1"});
SSLConnectionSocketFactory.buildSSLSocketFactory(webClientOptions);
答案 1 :(得分:0)
假设Sun / Oracle Java 6,因为您没有说IBM(以不同方式实现加密):
你的问题不是密码(BC-provider只有在问题缺乏ECC密码时才能解决),也不是协议。 https://www.ssllabs.com/ssltest/analyze.html?d=link.bollore-logistics.com表明服务器接受Java 6可以在没有任何扩充的情况下执行的密码和协议。
您的问题是SNI(服务器名称指示)。 ssllabs报告显示,唯一失败的模拟客户端是那些不发送SNI的客户端(Android 2,Windows XP,Java 6)用openssl进行的简单测试证实服务器需要SNI。 Java 6 JSSE没有实现SNI。
可能使用BC版本的JSSE - 这是一个单独的jar bctls-jdk15on-$ver
而不是bcprov-jdk15on-$ver
和providername BCJSSE而不是BC。在根据源代码的最新版本(1.57和1.58)中,如果使用域名(不是IPaddress或本地别名)进行连接,则在我看来客户端应该默认执行SNI。但是我无法验证,因为由于SecureRandom的一些问题,我现在无法实例化BCJSSE,因此我现在没有时间跟踪。