Java SSL контекст не инициализирован

#java #ssl #server #ssl-certificate #client

#java #ssl #сервер #ssl-сертификат #клиент

Вопрос:

Здравствуйте, я пытаюсь запустить сервер SSL и клиентскую программу. Сначала я создаю сертификат с помощью команды cmd «keytool -genkey -keystore mySrvKeyStore -keyalg RSA». 123456 — это пароль после ввода информации. Я помещаю сертификат в ту же папку, что и сервер и клиент, запускаю сервер и получаю следующую ошибку: «java.lang.Исключение IllegalStateException: SSLContext не инициализирован »

Сервер:

 public class SSLServer {

private static int port = 4000;
private static SSLServerSocketFactory sf;
private static SSLServerSocket ss;

public static void StabilireConexiune(int nrPort) {
    try {
        sf = (SSLServerSocketFactory) SSLServer.getServerSocketFactory();
        ss = (SSLServerSocket) sf.createServerSocket(nrPort);
        System.out.println("Server connected ready to accept new connections at the address "   ss.getLocalPort());
        String[] enable = {"TLS_DH_anon_WITH_AES_128_CBC_SHA"};
        ss.setEnabledCipherSuites(enable);
        String[] cipherSuites = ss.getEnabledCipherSuites();
        System.out.println("CipherSuites: ");
        for (int i = 0; i < cipherSuites.length; i  ) {
            System.out.println(cipherSuites[i]);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

private static SSLSocket clientSocket;

public static void ConectareClient(){
    
    try{
        clientSocket = (SSLSocket) ss.accept();
        System.out.println("Client connected succesfully");
        
        InputStream input = clientSocket.getInputStream();
        InputStreamReader inputreader = new InputStreamReader(input);
        BufferedReader br = new BufferedReader(inputreader);
        String string = null;
        
        while( (string = br.readLine()) != null){
            System.out.println(string);
            System.out.flush();
        }

    }catch(Exception ex){
        ex.printStackTrace();
    }
    finally{
        try{
            clientSocket.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }
}

private static ServerSocketFactory getServerSocketFactory() throws NoSuchAlgorithmException{
    
    SSLServerSocketFactory ssf = null;
    try{
        KeyManagerFactory kmf;
        KeyStore ks;
    SSLContext ctx;
        
        char[] passphrase = "123456".toCharArray();
        
        ctx = SSLContext.getInstance("TLS");
        kmf = KeyManagerFactory.getInstance("SunX509");
        ks = KeyStore.getInstance("JKS");
        
        ks.load(new FileInputStream("mySrvKeystore"), passphrase);
        kmf.init(ks, passphrase);
        ctx.getServerSocketFactory();
        
        return ssf;
    }catch(Exception ex){
        ex.printStackTrace();
    }
    return null;
}

public static void main(String args[]){
    if(args.length != 0){
        port = Integer.parseInt(args[0]);
    }
    
    
    StabilireConexiune(port);
    while(true){
        ConectareClient();
    }
}}
 

Клиент:

 public class SSLClient {

public static void main(String args[]) {
    conectare("127.0.0.1", 4000);
}

private static SSLSocket socket;

public static void conectare(String host, int port) {

    try {
        SSLSocketFactory factory = (SSLSocketFactory) SSLClient.getSocketFactory();
        socket = (SSLSocket) factory.createSocket(host, port);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] enable = {"TLS_DH_anon_WITH_AES_128_CBC_SHA"};
        socket.setEnabledCipherSuites(enable);
        String[] cipherSuites = socket.getEnabledCipherSuites();
        for (int i = 0; i < cipherSuites.length; i  ) {
            System.out.println(cipherSuites[i]);
        }
        socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
            public void handshakeCompleted(HandshakeCompletedEvent event) {
                System.out.println("handshake done");
            }
        });
        socket.startHandshake();
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
        System.out.println("Give a message to the server...");
        String string = br.readLine();
        out.println("Message to the server..."   string);
        out.println();
        out.flush();
    }catch(IOException ex){
        ex.printStackTrace();
    }
    finally{
        try{
            socket.close();
        }catch(IOException ex){
           ex.printStackTrace();
        }
    }
}

private static SocketFactory getSocketFactory(){
    SSLSocketFactory ssf = null; 
    try{
        SSLContext ctx;
        KeyManagerFactory kmf;
        KeyStore ks;
        
        char[] passphrase = "123456".toCharArray();
        
        ctx = SSLContext.getInstance("TLS");
        kmf = KeyManagerFactory.getInstance("SunX509");
        ks = KeyStore.getInstance("JKS");
        
        ks.load(new FileInputStream("mySrvKeystore"), passphrase);
        kmf.init(ks, passphrase);
        ctx.init(kmf.getKeyManagers(), null, null);
        ssf = ctx.getSocketFactory();
        
        return ssf;
    }catch(Exception e){
        e.printStackTrace();
    }
    return null;
}}
 

Пожалуйста, помогите мне, в чем проблема?

Ответ №1:

Ошибка в этих двух строках:

  SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.getServerSocketFactory();
 

Почему он выдает это исключение? Метод getServerSocketFactory() утверждает:

Выдает: исключение IllegalStateException — если SSLContextImpl требует инициализации, а init() не был вызван

В клиенте вы действительно вызываете ctx.init(kmf.getKeyManagers(), null, null); перед вызовом ctx.getServerSocketFactory();

Но на сервере вы не вызываете это — вы только инициализируете KeyManagerFactory.

Комментарии:

1. Большое вам спасибо. Я добавил строку, и теперь она работает.