javax.net.ssl.SSLHandshakeException:null cert chain null cert chain

时间:2017-02-21 15:04:01

标签: java ssl exception

我有一台服务器而且我有一个客户端。我让它们都在同一台机器上运行。我正在尝试在客户端和服务器之间建立SSL连接。我使用以下keytool命令为服务器和客户端生成了证书。

对于客户 keytool -keystore clientstore -genkey -alias client -validity 3650

然后我将客户端的根证书导出到cer文件callled client.cer

对于服务器 keytool -keystore serverstore -genkey -alias server -validity 3650 然后我将服务器的根证书导出到cer文件callled server.cer

我现在使用以下命令将客户端证书“client.cer”导入serverstore密钥库

keytool -import -keystore serverstore -file client.cer -alias client

并使用以下命令

将服务器证书“server.cer”导入clientstore密钥库

keytool -import -keystore clientstore -file server.cer -alias server

执行此操作后,我将server.cer和client.cer都导入到cacerts Keystore中。但是当我尝试建立一个ssl连接时,我在服务器 javax.net.ssl.SSLHandshakeException:null cert chain 上收到此错误,并且客户端上的此错误javax.net.ssl.SSLHandshakeException:Received致命警报:bad_certificate。

我的服务器代码。

package serverapplicationssl;


import java.io.*;
import java.security.KeyStore;
import java.security.Security;
import java.security.PrivilegedActionException;

import javax.net.ssl.*;
import com.sun.net.ssl.internal.ssl.Provider;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;

import java.io.*;

public class ServerApplicationSSL {

public static void main(String[] args) {
    boolean debug = true;

    System.out.println("Waiting For Connection");

    int intSSLport = 4447;

    {
        Security.addProvider(new Provider());

    }
    if (debug) {
        System.setProperty("javax.net.debug", "all");
    }
    FileWriter file = null;
    try {
        file = new FileWriter("C:\\SSLCERT\\Javalog.txt");

    } catch (Exception ee) {
        //message = ee.getMessage();

    }

    try {

        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(new FileInputStream("C:\\SSLCERT\\OntechServerKS"), "server".toCharArray());
        file.write("Incoming Connection\r\n");

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                .getDefaultAlgorithm());
        kmf.init(keystore, "server".toCharArray());

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(kmf.getKeyManagers(), null, null);

        SSLServerSocketFactory sslServerSocketfactory = (SSLServerSocketFactory) context.getServerSocketFactory();
        SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(intSSLport);
        sslServerSocket.setEnabledCipherSuites(sslServerSocket.getSupportedCipherSuites());
        sslServerSocket.setNeedClientAuth(true);
        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
        //SSLServerSocket server_socket = (SSLServerSocket) sslServerSocket;

        sslSocket.startHandshake();

     // Start the session
        System.out.println("Connection Accepted");
        file.write("Connection Accepted\r\n");

        while (true) {
            PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);

            String inputLine;

            //while ((inputLine = in.readLine()) != null) {
            out.println("Hello Client....Welcome");
            System.out.println("Hello Client....Welcome");
            //}

            out.close();
            //in.close();
            sslSocket.close();
            sslServerSocket.close();
            file.flush();
            file.close();
        }

    } catch (Exception exp) {
        try {
            System.out.println(exp.getMessage() + "\r\n");
            exp.printStackTrace();
            file.write(exp.getMessage() + "\r\n");
            file.flush();
            file.close();
        } catch (Exception eee) {
            //message = eee.getMessage();
        }

    }

}

}

这是我的客户代码

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.Enumeration;

import javax.net.ssl.*;

public class SSLConnect {

public String MakeSSlCall(String meternum) {
    String message = "";
    FileWriter file = null;
    try {
        file = new FileWriter("C:\\SSLCERT\\ClientJavalog.txt");

    } catch (Exception ee) {
        message = ee.getMessage();

    }
    //writer = new BufferedWriter(file );
    try {
        file.write("KeyStore Generated\r\n");
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(new FileInputStream("C:\\SSLCERT\\SkyeClientKS"), "client".toCharArray());

        file.write("KeyStore Generated\r\n");
        Enumeration enumeration = keystore.aliases();
        while (enumeration.hasMoreElements()) {
            String alias = (String) enumeration.nextElement();
            file.write("alias name: " + alias + "\r\n");
            keystore.getCertificate(alias);
            file.write(keystore.getCertificate(alias).toString() + "\r\n");
        }
        TrustManagerFactory tmf =TrustManagerFactory.getInstance("SunX509");
        tmf.init(keystore);
        file.write("KeyStore Stored\r\n");
        SSLContext context = SSLContext.getInstance("SSL");
        TrustManager[] trustManagers = tmf.getTrustManagers();
        context.init(null, trustManagers, null);

        SSLSocketFactory f = context.getSocketFactory();
        file.write("About to Connect to Ontech\r\n");
        SSLSocket c = (SSLSocket) f.createSocket("192.168.1.16", 4447);
        file.write("Connection Established to 196.14.30.33 Port: 8462\r\n");
        file.write("About to Start Handshake\r\n");
        c.startHandshake();
        file.write("Handshake Established\r\n");
        file.flush();
        file.close();
        return "Connection Established";
    } catch (Exception e) {
        try {
            file.write("An Error Occured\r\n");
            file.write(e.getMessage() + "\r\n");
            StackTraceElement[] arrmessage = e.getStackTrace();
            for (int i = 0; i < arrmessage.length; i++) {
                file.write(arrmessage[i] + "\r\n");
            }

            file.flush();
            file.close();
        } catch (Exception eee) {
            message = eee.getMessage();

        }
        return "Connection Failed";
    }
}
}

我的服务器上的堆栈跟踪执行

javax.net.ssl.SSLHandshakeException: null cert chain
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1937)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:292)
    at sun.security.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1804)
    at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:222)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:957)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:892)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1050)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at serverapplicationssl.ServerApplicationSSL.main(ServerApplicationSSL.java:69)

在我的客户端上执行Stack Trace Execption

Received fatal alert: bad_certificate
sun.security.ssl.Alerts.getSSLException(Unknown Source)
sun.security.ssl.Alerts.getSSLException(Unknown Source)
sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
SSLConnect.MakeSSlCall(SSLConnect.java:96)
BankCollectSSLCon.main(BankCollectSSLCon.java:13)

可能导致此错误的原因是什么?可能是因为我在同一台计算机上同时运行服务器和客户端?...现在已经有一段时间了。我需要帮助

1 个答案:

答案 0 :(得分:2)

@WiteCastle是的,我做到了,相信我,我有一个真正不愉快的经历,找出问题所在。在粘贴我的代码片段之前,让我先解释客户端和服务器之间的SSL Communication.SSL连接。

  1. 客户说你好
  2. 服务器说你好。
  3. 服务器呈现。验证证书。
  4. 客户端检查证书是否在其TrustStore中。
  5. 服务器请求客户端证书。
  6. 客户端提供服务器验证证书。
  7. 如果客户端证书通过验证通信现在可以 发生。
  8. 因此,当客户端证书在服务器上验证失败并且javax.net.ssl.SSLHandshakeException时发生javax.net.ssl.SSLHandshakeException:null证书链错误:收到致命警报:当服务器找不到客户端证书时发生bad_certificate在其信任库中呈现。 所以我做的是

    对于客户

    import java.io.*;
    import java.net.*;
    import java.security.*;
    import java.util.Enumeration;
    
    import javax.net.ssl.*;
    
    public class SSLConnect {
    
    public String MakeSSlCall(String meternum) {
    String message = "";
    FileWriter file = null;
    try {
        file = new FileWriter("C:\\SSLCERT\\ClientJavalog.txt");
    
    } catch (Exception ee) {
        message = ee.getMessage();
    
    }
    //writer = new BufferedWriter(file );
    try {
        file.write("KeyStore Generated\r\n");
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(new FileInputStream("C:\\SSLCERT\\SkyeClientKS"), 
    "client".toCharArray());
    
        file.write("KeyStore Generated\r\n");
        Enumeration enumeration = keystore.aliases();
        while (enumeration.hasMoreElements()) {
            String alias = (String) enumeration.nextElement();
            file.write("alias name: " + alias + "\r\n");
            keystore.getCertificate(alias);
            file.write(keystore.getCertificate(alias).toString() + "\r\n");
        }
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                    .getDefaultAlgorithm());
            kmf.init(keystore, KeystorePassword.toCharArray());
        TrustManagerFactory tmf =TrustManagerFactory.getInstance("SunX509");
        tmf.init(keystore);
        file.write("KeyStore Stored\r\n");
        SSLContext context = SSLContext.getInstance("SSL");
        TrustManager[] trustManagers = tmf.getTrustManagers();
    
        context.init(kmf.getKeyManagers(), trustManagers, null);
    
        SSLSocketFactory f = context.getSocketFactory();
        file.write("About to Connect to Ontech\r\n");
        SSLSocket c = (SSLSocket) f.createSocket("192.168.1.16", 4447);
        file.write("Connection Established to 196.14.30.33 Port: 8462\r\n");
        file.write("About to Start Handshake\r\n");
        c.startHandshake();
        file.write("Handshake Established\r\n");
        file.flush();
        file.close();
        return "Connection Established";
    
    } catch (Exception e) {
        try {
            file.write("An Error Occured\r\n");
            file.write(e.getMessage() + "\r\n");
            StackTraceElement[] arrmessage = e.getStackTrace();
            for (int i = 0; i < arrmessage.length; i++) {
                file.write(arrmessage[i] + "\r\n");
            }
    
            file.flush();
            file.close();
        } catch (Exception eee) {
            message = eee.getMessage();
    
        }
        return "Connection Failed";
    }
    }
    }
    

    对于服务器

    package serverapplicationssl;
    
    
    import java.io.*;
    import java.security.KeyStore;
    import java.security.Security;
    import java.security.PrivilegedActionException;
    
    import javax.net.ssl.*;
    import com.sun.net.ssl.internal.ssl.Provider;
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    import java.security.Security;
    
    import java.io.*;
    
    public class ServerApplicationSSL {
    
    public static void main(String[] args) {
    boolean debug = true;
    
    System.out.println("Waiting For Connection");
    
    int intSSLport = 4447;
    
    {
        Security.addProvider(new Provider());
    
    }
    if (debug) {
        System.setProperty("javax.net.debug", "all");
    }
    FileWriter file = null;
    try {
        file = new FileWriter("C:\\SSLCERT\\Javalog.txt");
    
    } catch (Exception ee) {
        //message = ee.getMessage();
    
    }
    
    try {
    
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(new FileInputStream("C:\\SSLCERT\\OntechServerKS"), 
    "server".toCharArray());
        file.write("Incoming Connection\r\n");
    
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                .getDefaultAlgorithm());
        kmf.init(keystore, "server".toCharArray());
    
        TrustManagerFactory tmf =TrustManagerFactory.getInstance("SunX509");
        tmf.init(keystore);
        file.write("KeyStore Stored\r\n");
        TrustManager[] trustManagers = tmf.getTrustManagers();
    
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(kmf.getKeyManagers(), trustManagers, null);
    
        SSLServerSocketFactory sslServerSocketfactory = (SSLServerSocketFactory) context.getServerSocketFactory();
        SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(intSSLport);
        sslServerSocket.setEnabledCipherSuites(sslServerSocket.getSupportedCipherSuites());
        sslServerSocket.setNeedClientAuth(true);
        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
        //SSLServerSocket server_socket = (SSLServerSocket) sslServerSocket;
    
        sslSocket.startHandshake();
    
     // Start the session
        System.out.println("Connection Accepted");
        file.write("Connection Accepted\r\n");
    
        while (true) {
            PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);
    
            String inputLine;
    
            //while ((inputLine = in.readLine()) != null) {
            out.println("Hello Client....Welcome");
            System.out.println("Hello Client....Welcome");
            //}
    
            out.close();
            //in.close();
            sslSocket.close();
            sslServerSocket.close();
            file.flush();
            file.close();
        }
    
    } catch (Exception exp) {
        try {
            System.out.println(exp.getMessage() + "\r\n");
            exp.printStackTrace();
            file.write(exp.getMessage() + "\r\n");
            file.flush();
            file.close();
        } catch (Exception eee) {
            //message = eee.getMessage();
        }
    
        }
    
    }
    
    }