getLocalCertificates () возвращает ноль - PullRequest
0 голосов
/ 22 сентября 2018

Я пытаюсь написать простую программу сокета сервера ssl и клиента сокета.сначала я получил настоящий сертификат, а затем я использовал первый код для генерации хранилища ключей для него.Затем я написал код сервера и клиента, чтобы мой сервер использовал это хранилище ключей в качестве сертификата сервера, но сертификат не отправлялся во время соединения, и session.getLocalCertificates () только возвращает null код генерации моего хранилища ключей:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.KeyStore;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class MainClass {
    public static void main(String args[]) throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        List mylist = new ArrayList();

            FileInputStream in = new FileInputStream("C:\\Users\\nima\\Downloads\\72315359_example.com.cert");
            Certificate cr = cf.generateCertificate(in);
            mylist.add(cr);

        CertPath cp = cf.generateCertPath(mylist);
        System.out.println(cp);

        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(null, null);
        List cplist = cp.getCertificates();
        Object[] o = cplist.toArray();
        for (int i = 0; i < o.length; i++) {
            X509Certificate c = (X509Certificate) o[i];
            ks.setCertificateEntry("my" + i, c);
        }
        FileOutputStream output = new FileOutputStream("C:\\Users\\nima\\Downloads\\test.dat");
        ks.store(output, "mypass".toCharArray());
        output.close();

    }
}

код моего сервера:

import java.io.PrintStream;
import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

public class MainClass {
    public static void main(String args[]) throws Exception {
        System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\nima\\Downloads\\test.dat");
        System.setProperty("javax.net.ssl.keyStorePassword", "mypass");

        SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        ServerSocket ss = ssf.createServerSocket(5432);
        while (true) {
            Socket s = ss.accept();
            SSLSession session = ((SSLSocket) s).getSession();
            Certificate[] cchain2 = session.getLocalCertificates();
            for (int i = 0; i < cchain2.length; i++) {
                System.out.println(((X509Certificate) cchain2[i]).getSubjectDN());
            }
            System.out.println("Peer host is " + session.getPeerHost());
            System.out.println("Cipher is " + session.getCipherSuite());
            System.out.println("Protocol is " + session.getProtocol());
            System.out.println("ID is " + new BigInteger(session.getId()));
            System.out.println("Session created in " + session.getCreationTime());
            System.out.println("Session accessed in " + session.getLastAccessedTime());

            PrintStream out = new PrintStream(s.getOutputStream());
            out.println("Hi");
            out.close();
            s.close();
        }

    }
}

мой код клиента:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class MainClass {
    public static void main(String args[]) throws Exception {
        System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\nima\\Downloads\\test.dat");

        SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
        Socket s = ssf.createSocket("127.0.0.1", 5432);

        SSLSession session = ((SSLSocket) s).getSession();
        Certificate[] cchain = session.getPeerCertificates();
        System.out.println("The Certificates used by peer");
        for (int i = 0; i < cchain.length; i++) {
            System.out.println(((X509Certificate) cchain[i]).getSubjectDN());
        }
        System.out.println("Peer host is " + session.getPeerHost());
        System.out.println("Cipher is " + session.getCipherSuite());
        System.out.println("Protocol is " + session.getProtocol());
        System.out.println("ID is " + new BigInteger(session.getId()));
        System.out.println("Session created in " + session.getCreationTime());
        System.out.println("Session accessed in " + session.getLastAccessedTime());

        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String x = in.readLine();
        System.out.println(x);
        in.close();

    }
}

мой код сервера от здесь и на стороне сервера и на стороне клиента я получаю нулевое значение от getLocalCertificates.Также возможно, что весь мой код будет неправильным.

1 Ответ

0 голосов
/ 26 сентября 2018

(из комментариев, немного расширен)

Если SSLSocket.getSession() вызывается до того, как рукопожатие выполнено, он пытается это сделать, но если рукопожатие не удается getSession() глотает исключение и просто возвращает 'объект nullSession, который не имеет данных, которые имел бы реальный объект сеанса.Либо (1) установите sysprop javax.net.debug=ssl (при запуске, обычно в командной строке с -D) и посмотрите, что в нем записано, чтобы увидеть, что не так с вашим рукопожатием, либо (2) явно вызовите ((SSLSocket)s).startHandshake() (который, несмотря наимя на самом деле запускает рукопожатие до завершения, успешно или нет) и посмотреть, что оно бросает.

В частности, если вы используете файл хранилища ключей, созданный с помощью первого показанного кода, который содержит только сертификат (trustedCertEntry), а не privateKeyEntry (как с privatekey, так и с сертификатом / цепочкой), как это необходимо и требуется для SSL /TLS-сервер для использования любого из стандартных и включенных по умолчанию пакетов;эта ошибка обычно проявляется в некотором замешательстве как сбой при рукопожатии, когда «нет общего шифра [набора]] или« нет совпадения шифра [набора] ».

Эта вторая часть (сервер SSL / TLS без приватного ключа не работает) много раз спрашивалась и отвечала, но я не помню ни одной ошибки, которая также включает часть 'getSession маскирует ошибку'.

...