使用Java 6,HTMLUnit和Bouncy Castle使用TLSv1进行SSL握手失败

时间:2017-12-06 03:38:49

标签: ssl htmlunit handshake sslcontext

我正在尝试使用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);

2 个答案:

答案 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,因此我现在没有时间跟踪。