有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java SSLsocket连接错误

我正在使用Java8。我正在尝试使用客户端证书和证书树连接socket服务器

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

  1. 客户证书(PEM)
  2. 私钥(PEM)
  3. CA树(PEM)-具有4个证书

我已经创建了密钥库。jks使用以下步骤:

  1. 使用cat将客户端证书和CA树合并到单个pem文件中

  2. 使用私钥(OpenSSL命令)加密的组合文件中的带顶PKCS12文件

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

我创造了信任。jks使用以下步骤:

  1. 将CA树(4个证书)拆分为4个不同的文件
  2. 通过逐个导入每个文件,使用keytool生成trustore文件

我的示例代码如下:

    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”消息,但在该应用程序引发上述异常之后

我做错了什么?请给出建议

谢谢, 索姆纳特·古哈


共 (1) 个答案

  1. # 1 楼答案

    在分析调试lo之后,我发现了这个问题

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

    基本约束:[ CA:是的 路径:2147483647 ]