ssl连接中的握手失败bewteen客户端/服务器java

时间:2015-09-15 16:36:11

标签: java ssl

我试图通过SSL编写服务器/客户端通信,每一方都有自己的密钥库和证书,双方都需要相互验证。我自定义TrustManager以允许默认情况下验证不在信任库中的证书。我通过keytool生成密钥和证书。但是我首先在服务器端遇到了以下错误:

    trigger seeding of SecureRandom
    done seeding SecureRandom
    Allow unsafe renegotiation: false
    Allow legacy hello messages: true
    Is initial handshake: true
    Is secure renegotiation: false
    Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for SSLv2Hello
    Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
    Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
    Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
    Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
    Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
    Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
    Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
    Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
    Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
    [Raw read]: length = 5
    0000: 16 03 01 00 6B                                     ....k
    [Raw read]: length = 107
    0000: 01 00 00 67 03 01 55 F8   3A 82 11 AC ED 80 B3 32  ...g..U.:......2
    0010: E4 0D 03 A2 21 2F 87 84   29 81 48 E7 98 0D 59 9A  ....!/..).H...Y.
    0020: 2D B7 D2 76 67 B2 00 00   2C C0 0A C0 14 00 35 C0  -..vg...,.....5.
    0030: 05 C0 0F 00 39 00 38 C0   09 C0 13 00 2F C0 04 C0  ....9.8...../...
    0040: 0E 00 33 00 32 C0 08 C0   12 00 0A C0 03 C0 0D 00  ..3.2...........
    0050: 16 00 13 00 FF 01 00 00   12 00 0A 00 08 00 06 00  ................
    0060: 17 00 18 00 19 00 0B 00   02 01 00                 ...........
    main, READ: TLSv1 Handshake, length = 107
    *** ClientHello, TLSv1
    RandomCookie:  GMT: 1425553794 bytes = { 17, 172, 237, 128, 179, 50, 228, 13, 3, 162, 33, 47, 135, 132, 41, 129, 72, 231, 152, 13, 89, 154, 45, 183, 210, 118, 103, 178 }
    Session ID:  {}
    Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 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_EMPTY_RENEGOTIATION_INFO_SCSV]
    Compression Methods:  { 0 }
    Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1}
    Extension ec_point_formats, formats: [uncompressed]
    ***
    [read] MD5 and SHA1 hashes:  len = 107
    0000: 01 00 00 67 03 01 55 F8   3A 82 11 AC ED 80 B3 32  ...g..U.:......2
    0010: E4 0D 03 A2 21 2F 87 84   29 81 48 E7 98 0D 59 9A  ....!/..).H...Y.
    0020: 2D B7 D2 76 67 B2 00 00   2C C0 0A C0 14 00 35 C0  -..vg...,.....5.    
    0030: 05 C0 0F 00 39 00 38 C0   09 C0 13 00 2F C0 04 C0  ....9.8...../...
    0040: 0E 00 33 00 32 C0 08 C0   12 00 0A C0 03 C0 0D 00  ..3.2...........
    0050: 16 00 13 00 FF 01 00 00   12 00 0A 00 08 00 06 00  ................
    0060: 17 00 18 00 19 00 0B 00   02 01 00                 ...........
    %% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
    %% Invalidated:  [Session-1, SSL_NULL_WITH_NULL_NULL]
    main, SEND TLSv1 ALERT:  fatal, description = handshake_failure
    main, WRITE: TLSv1 Alert, length = 2
    [Raw write]: length = 7
    0000: 15 03 01 00 02 02 28                               ......(
    main, called closeSocket()
    main, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
    Exception in thread "main" javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1916)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:269)
    at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:969)
    at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:683)
    at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:221)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:837)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1035)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:901)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at ps.connection.SSLConnectionServer.doServerSide(SSLConnectionServer.java:49)
    at ps.connection.SSLConnectionServer.main(SSLConnectionServer.java:64)

这是服务器端的代码:

        KeyStore keyStore = KeyStore.getInstance("JKS");
        String storeFile = pathToStores + "/" + keyStoreFile;
        InputStream fileInput = new FileInputStream(storeFile);
        keyStore.load(fileInput, passwd.toCharArray());
        fileInput.close();

        KeyManagerFactory keyManagerFac = KeyManagerFactory.getInstance("SunX509");
        keyManagerFac.init(keyStore, passwd.toCharArray());

        SSLContext sslContext = SSLContext.getInstance("TLSv1");

        String trustFile = pathToStores + "/" + trustStoreFile;
        TrustManager [] trustManager = new TrustManager[]{new ReloadableX509TrustManager(trustFile, passwd)};
        sslContext.init(keyManagerFac.getKeyManagers(), trustManager, null);

        SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory
                .getDefault();
        SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(theServerPort);
        sslServerSocket.setNeedClientAuth(false);

        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
        String[] ciphers = sslSocket.getEnabledCipherSuites();

        InputStream sslIn = sslSocket.getInputStream();
        BufferedReader bufferReader = new BufferedReader(new InputStreamReader(sslIn));

        String str = null;
        while ((str = bufferReader.readLine()) != null){
            System.out.println(str);
            System.out.flush();
        }

        sslSocket.close();

以下是客户端的代码:

        KeyStore keyStore = KeyStore.getInstance("JKS");
        String keyFile = pathToStore + "/" + keyStoreFile;
        InputStream keyInput = new FileInputStream(keyFile);
        keyStore.load(keyInput, passwd.toCharArray());
        keyInput.close();

        KeyManagerFactory keyManagerFac = KeyManagerFactory.getInstance("SunX509");
        keyManagerFac.init(keyStore, passwd.toCharArray());

        SSLContext sslContext = SSLContext.getInstance("TLSv1");

        String trustFile = pathToStore + "/" + trustStoreFile;

        TrustManager [] trustManager = new TrustManager[]{new ReloadableX509TrustManager(trustFile, passwd)};
        sslContext.init(keyManagerFac.getKeyManagers(), trustManager, null);

        SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(theServerName, theServerPort);
        String[] ciphers = sslSocket.getEnabledCipherSuites();

        sslSocket.addHandshakeCompletedListener(new HandShakeListener());
        sslSocket.startHandshake();

        OutputStream sslOut = sslSocket.getOutputStream();
        sslOut.write("Hello RelayServer".getBytes());
        sslOut.flush();
        sslOut.close();
        sslSocket.close();

我在Ubuntu上使用Oracle java 7。任何提示表示赞赏!

1 个答案:

答案 0 :(得分:1)

使用密钥和信任存储初始化SSLContext时,以后不会使用上下文。您使用了与上下文无关的SSL[Server]SocketFactory.getDefault()。服务器失败,因为它没有指定密钥库。

尝试使用get[Server]SocketFactory()中的SSLContext方法。

另请阅读JSSE Guide