SSL套接字连接错误

时间:2016-12-06 19:58:04

标签: java sockets certificate ssl-certificate pem

我正在使用JAVA 8.我正在尝试使用客户端证书和证书树连接套接字服务器。

我有以下客户提供的信息:

  1. 客户CERT(PEM)
  2. 私钥(PEM)
  3. CA Tree(PEM) - 包含4个证书
  4. 我使用以下步骤创建了keystore.jks:

    1. 使用cat

    2. 在单个pem文件中组合客户端证书和CA树
    3. 使用私钥加密的组合文件中的Crested PKCS12文件(OpenSSL命令)

    4. 使用keytool生成的JKS密钥库文件

    5. 我使用以下步骤创建了trustore.jks:

      1. 将CA Tree(4个证书)拆分为4个不同的文件
      2. 通过逐个导入每个文件使用keytool生成的信任文件
      3. 我的示例代码如下:

            package com.tutorial.exception.customize;
        
        import javax.net.ssl.SSLHandshakeException;
        import javax.net.ssl.SSLSocket;
        import javax.net.ssl.SSLSocketFactory;
        import java.io.*;
        import java.security.cert.CertPathValidatorException;
        import java.security.cert.CertificateException;
        import java.util.Scanner;
        
        /**
         * Created by SomnathG on 12/1/2016.
         */
        public class Client {
            public Client() {
        
                System.setProperty("javax.net.ssl.keyStore", {keystore Location});
                System.setProperty("javax.net.ssl.keyStorePassword", {password});
                System.setProperty("javax.net.ssl.trustStore", {trustore location});
                System.setProperty("javax.net.ssl.trustStorePassword", {password});
                System.setProperty("javax.net.debug", "all");
        
                System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );
            }
        
            public void connectHost(){
                SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
                SSLSocket sslSocket = null;
                try {
        
                    sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
                    sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
        
                    sslSocket.startHandshake();
        
                    InputStream inputStream = sslSocket.getInputStream();
                    OutputStream outputStream = sslSocket.getOutputStream();
                    System.out.println("Sending request to Socket Server");
                    outputStream.write("Hello".getBytes());
                    outputStream.write("exit".getBytes());
                    byte[] messageByte = new byte[1000];
                    boolean end = false;
                    String dataString = "";
                    int bytesRead = 0;
                    String messageString = "";
                    DataInputStream in = new DataInputStream(sslSocket.getInputStream());
        
                    while(!end)
                    {
                        bytesRead = in.read(messageByte);
                        messageString += new String(messageByte, 0, bytesRead);
                        if (messageString.length() == 100)
                        {
                            end = true;
                        }
                    }
                    System.out.println("MESSAGE: " + messageString);
                    // byte[] read = (byte[]) ois.readObject();
                    //String s2 = new String(read);
                    //System.out.println("" + s2);
                    //System.out.println("Message: " + message);
                    //close resources
        
                    //System.out.println(receive(inputStream));
        
        
                }catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("=====");
                    System.out.println(e.getMessage());
                    System.out.println("=====");
                    CertPathValidatorException ce = new CertPathValidatorException(e);
                    System.out.println("******");
                    System.out.println(ce.getIndex());
                    System.out.println(ce.getReason());
                    System.out.println("******");
                    //e.printStackTrace();
                }
        
            }
        
            public static void main(String[] args){
                new Client().connectHost();
            }
        }
        

        我在执行代码后遇到异常:

            javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: basic constraints check failed: this is not a CA certificate
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
        at com.tutorial.exception.customize.Client.connectHost(Client.java:33)
        at com.tutorial.exception.customize.Client.main(Client.java:82)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
        

        在分析了日志之后,我发现了“clientHello”和“serverHello”消息,但是在该应用程序抛出上述异常之后。

        我做错了什么?请指教。

        谢谢, Somnath Guha

1 个答案:

答案 0 :(得分:1)

在分析调试后,我已经找到了问题。

" BasicConstraints"服务器V3证书中缺少该证书,因此java无法将证书识别为有效证书。一旦添加了该约束,客户端就能够与服务器握手并能够与服务器通信。

BasicConstraints:   CA:真   pathLen不能:2147483647 ]