2015-02-09 92 views
10

我试图连接到带有加密的Web服务器。 Web服务器仅允许使用TLSv1.2协议的连接。Java 7和TLSv1.2套接字

我从official doc

import java.net.*; 
import java.io.*; 
import javax.net.ssl.*; 

/* 
* This example demostrates how to use a SSLSocket as client to 
* send a HTTP request and get response from an HTTPS server. 
* It assumes that the client is not behind a firewall 
*/ 

public class SSLSocketClient { 

public static void main(String[] args) throws Exception { 
    try { 
     String host = "172.20.172.106"; 
     SSLSocketFactory factory = 
       (SSLSocketFactory) SSLSocketFactory.getDefault(); 
     SSLSocket socket = (SSLSocket) factory.createSocket(host, 443); 
     String[] protocols = socket.getEnabledProtocols(); 
     System.out.println("Enabled Protocols: "); 
     for (int i = 0; i < protocols.length; i++) { 
      System.out.println(protocols[i] + ", "); 
     } 
     String[] supportedProtocols = socket.getSupportedProtocols(); 
     System.out.println("Supported Protocols: "); 
     for (int i = 0; i < protocols.length; i++) { 
      System.out.println(supportedProtocols[i] + ", "); 
     } 
     String[] goodProtocols = new String[1]; 
     goodProtocols[0] = "TLSv1.2"; 
     socket.setEnabledProtocols(goodProtocols); 
     protocols = socket.getEnabledProtocols(); 
     System.out.println("Set Protocols: "); 
     for (int i = 0; i < protocols.length; i++) { 
      System.out.println(protocols[i] + ", "); 
     } 
     /* 
     * send http request 
     * 
     * Before any application data is sent or received, the 
     * SSL socket will do SSL handshaking first to set up 
     * the security attributes. 
     * 
     * SSL handshaking can be initiated by either flushing data 
     * down the pipe, or by starting the handshaking by hand. 
     * 
     * Handshaking is started manually in this example because 
     * PrintWriter catches all IOExceptions (including 
     * SSLExceptions), sets an internal error flag, and then 
     * returns without rethrowing the exception. 
     * 
     * Unfortunately, this means any error messages are lost, 
     * which caused lots of confusion for others using this 
     * code. The only way to tell there was an error is to call 
     * PrintWriter.checkError(). 
     */ 
     socket.startHandshake(); 

     PrintWriter out = new PrintWriter(
       new BufferedWriter(
         new OutputStreamWriter(
           socket.getOutputStream()))); 

     out.println("GET/HTTP/1.0"); 
     out.println(); 
     out.flush(); 

     /* 
     * Make sure there were no surprises 
     */ 
     if (out.checkError()) 
      System.out.println(
        "SSLSocketClient: java.io.PrintWriter error"); 

     /* read response */ 
     BufferedReader in = new BufferedReader(
       new InputStreamReader(
         socket.getInputStream())); 

     String inputLine; 
     while ((inputLine = in.readLine()) != null) 
      System.out.println(inputLine); 

     in.close(); 
     out.close(); 
     socket.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
} 

如果我运行JRE验证码8一切正常修改这个片段现在。

这是输出我得到

Enabled Protocols: 
TLSv1, 
TLSv1.1, 
TLSv1.2, 
Supported Protocols: 
SSLv2Hello, 
SSLv3, 
TLSv1, 
Set Protocols: 
TLSv1.2, 
HTTP/1.1 302 Moved Temporarily 
Connection: close 
Content-Type: text/html; charset=ISO-8859-1 
Content-Length: 0 
Date: Mon, 09 Feb 2015 15:08:25 GMT 
Expires: 0 
Cache-Control: no-cache 
X-Content-Type-Options: nosniff 
X-XSS-Protection: 1; mode=block 
Server: PRTG/15.1.13.1382 
Location: /index.htm 

但是,如果我尝试用JRE1.7.0_75与-Djavax.net.debug=all我得到以下

Enabled Protocols: 
TLSv1, 
Supported Protocols: 
SSLv2Hello, 
Set Protocols: 
TLSv1.2, 

keyStore is : 
keyStore type is : jks 
keyStore provider is : 
init keystore 
init keymanager of type SunX509 
trustStore is: C:\Program Files\Java\jdk1.7.0_75\jre\lib\security\cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 

...SKIPPING CERTIFICATE INIT... 

trigger seeding of SecureRandom 
done seeding SecureRandom 
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
Enabled Protocols: 
TLSv1, 
Supported Protocols: 
SSLv2Hello, 
Set Protocols: 
TLSv1.2, 
%% No cached client session 
*** ClientHello, TLSv1.2 
RandomCookie: GMT: 1406651565 bytes = { 85, 112, 165, 115, 135, 15, 171, 1, 167, 182, 47, 68, 233, 53, 164, 111, 112, 244, 51, 252, 240, 40, 178, 238, 204, 215, 13, 137 } 
Session ID: {} 
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA 
*** 
[write] MD5 and SHA1 hashes: len = 179 
0000: 01 00 00 AF 03 03 54 D8 CD AD 55 70 A5 73 87 0F ......T...Up.s.. 
0010: AB 01 A7 B6 2F 44 E9 35 A4 6F 70 F4 33 FC F0 28 ..../D.5.op.3..(
0020: B2 EE CC D7 0D 89 00 00 2A C0 09 C0 13 00 2F C0 ........*...../. 
0030: 04 C0 0E 00 33 00 32 C0 08 C0 12 00 0A C0 03 C0 ....3.2......... 
0040: 0D 00 16 00 13 C0 07 C0 11 00 05 C0 02 C0 0C 00 ................ 
0050: 04 00 FF 01 00 00 5C 00 0A 00 34 00 32 00 17 00 ......\...4.2... 
0060: 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 ................ 
0070: 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 ................ 
0080: 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 ................ 
0090: 0B 00 02 01 00 00 0D 00 1A 00 18 06 03 06 01 05 ................ 
00A0: 03 05 01 04 03 04 01 03 03 03 01 02 03 02 01 02 ................ 
00B0: 02 01 01           ... 
main, WRITE: TLSv1.2 Handshake, length = 179 
[Raw write]: length = 184 
0000: 16 03 03 00 B3 01 00 00 AF 03 03 54 D8 CD AD 55 ...........T...U 
0010: 70 A5 73 87 0F AB 01 A7 B6 2F 44 E9 35 A4 6F 70 p.s....../D.5.op 
0020: F4 33 FC F0 28 B2 EE CC D7 0D 89 00 00 2A C0 09 .3..(........*.. 
0030: C0 13 00 2F C0 04 C0 0E 00 33 00 32 C0 08 C0 12 .../.....3.2.... 
0040: 00 0A C0 03 C0 0D 00 16 00 13 C0 07 C0 11 00 05 ................ 
0050: C0 02 C0 0C 00 04 00 FF 01 00 00 5C 00 0A 00 34 ...........\...4 
0060: 00 32 00 17 00 01 00 03 00 13 00 15 00 06 00 07 .2.............. 
0070: 00 09 00 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E ................ 
0080: 00 0F 00 10 00 11 00 02 00 12 00 04 00 05 00 14 ................ 
0090: 00 08 00 16 00 0B 00 02 01 00 00 0D 00 1A 00 18 ................ 
00A0: 06 03 06 01 05 03 05 01 04 03 04 01 03 03 03 01 ................ 
00B0: 02 03 02 01 02 02 01 01       ........ 
[Raw read]: length = 5 
0000: 15 03 03 00 02          ..... 
[Raw read]: length = 2 
0000: 02 28            .(
main, READ: TLSv1.2 Alert, length = 2 
main, RECV TLSv1 ALERT: fatal, handshake_failure 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) 
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1979) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1086) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343) 
    at SSLSocketClient.main(SSLSocketClient.java:96) 

JDK7应该支持TLSv1.2工作,但我不” t看到它在支持的协议输出

+0

传递'-Ddeployment.security.TLSv1.1 =真-Ddeployment.security.TLSv1.2 = true'应该在Java 7中启用TLS 1.1和TLS 1.2。 – Petesh 2015-02-09 16:59:52

+0

@Petesh听起来像一个答案Petesh – 2015-02-09 21:39:25

+0

我已经尝试过并且不能工作 'C:\ Program Files \ Java \ jdk1.7.0_75 \ bin \ java''-Ddeployment.security.TLSv1.1 = true'' -Ddeployment.security.TLSv1.2 =真SSLSocketClient' '启用的协议:'' 的TLSv1,'' 支持的协议:'' SSLv2Hello,'' 组协议:'' TLSv1.2工作,'' javax.net.ssl.SSLHandshakeException:收到致命警报:''handshake_failure' – EmaB 2015-02-10 07:30:18

回答

4

最后我发现了问题:我试图连接时,PRTG服务器设置在模式SSL security: high security似乎只接受安全的con使用​​和密码TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 nections,即仅适用于Java的8

@Petesh感谢您的支持

7

PRTG支持4 ciphers与高安全性模式设置。

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 

这些都不是Java的标准分发1.7

然而,在Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download它包括TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

您需要下载无限强度拉链和更换local_policy.jarUS_export_policy.jar文件在JRE_HOME/lib/security中使用下载的。

编辑2016年2月12日:

您还需要启用通过系统属性相应的TLS版本:

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 
+1

我的确提出了解决方案,但同样的错误即将到来 – Salman 2016-08-25 08:31:44

+0

除了确保密码匹配之外,您还必须确保你的PRTG服务器使用的证书是你的java代码所信任的。如果它的内部证书等,您可能需要将证书添加到您的信任存储。 – Gary 2016-08-25 10:18:16

+0

是的,这解决了我的问题 – Dima 2017-05-11 17:54:19