Как просто сгенерировать SSL-сертификат и форму ServerSocket Java-кода - PullRequest
0 голосов
/ 12 октября 2010

Есть ли простой способ динамически генерировать недоверенный ssl-сертификат без домена и применить его к сокету сервера - все из кода, без командной строки или дополнительных файлов?

Цель - безопасное соединение между двумя хостами, которые знают только IP ипорт для связи друг с другом - сертификаты, генерируемые случайным образом при запуске сервера и используемые как «ненадежные», нет домена, поэтому нет проверки (если я не ошибаюсь).Я думаю, что это может быть полезно при защите передачи данных между центрами обработки данных в сторонних приложениях.

Это рабочий код для незашифрованного простого теста клиент-сервер.

package study.benchmark.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import org.junit.Test;

public class DynamicSSLTest {

    @Test
    public void sslServerSocketTest() throws Exception {

        System.out.println("ssl server test");

        final int port = 8750;

        // server

        Thread th = new Thread() {

            @Override
            public void run() {

                try {
                    //ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
                    ServerSocketFactory factory = ServerSocketFactory.getDefault();

                    ServerSocket server = factory.createServerSocket(port);
                    Socket socket = server.accept();

                    OutputStream out = socket.getOutputStream();
                    out.write("some data".getBytes());

                    socket.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

        th.start();

        //client

        //SocketFactory factory =  SSLSocketFactory.getDefault();
        SocketFactory factory = SocketFactory.getDefault();

        Socket socket = factory.createSocket("localhost", port);
        InputStream is = socket.getInputStream();

        StringBuffer sb = new StringBuffer();

        int data;
        while ((data = is.read()) >= 0) {
            System.out.print((char) data);
        }

        System.out.println();

        socket.close();

        th.join();
    }

}

Ответы [ 3 ]

1 голос
/ 12 октября 2010

Вы можете создать самозаверяющий сертификат динамически, используя библиотеку, такую ​​как BouncyCastle (по сути, для сертификата для самоподписания вы используете тот же DN эмитента, что и DN субъекта, и вы подписываете сзакрытый ключ, соответствующий открытому ключу сертификата).Затем вам нужно поместить его в KeyStore (по крайней мере, в памяти, необязательно в файл) и собрать из него SSLContext, чтобы иметь возможность построить SSLSocketFactory.

Это может быть полезно для тестирования, но это не сделает ваше приложение безопасным .Вообще говоря, шифрование без аутентификации удаленной стороны небезопасно.Вы можете обмениваться информацией так же «тайно», как и с удаленной стороной, но если вы не проверили ее личность, вы не уверены, что ваши секреты переданы предполагаемому получателю.

Если ваш сертификатгенерируемый динамически, вам нужно будет найти способ, чтобы клиент узнал, что это действительно законный сертификат, прежде чем делать какие-либо вызовы на этот сервер.

Общий подход SSH (где предполагается, что мало кто на самом деле проверяет отпечатки пальцев, которые ониустановление первого соединения - некоторые люди действительно проверяют вне группы) - это компромисс, при котором клиенты, как правило, принимают ключ (более или менее вслепую) в первый раз, но будут предупреждены, если он изменился.Вы также можете реализовать такой подход для обработки доверия сертификатов X.509, но если вы будете заново генерировать новый самозаверяющий сертификат каждый раз при перезапуске сервера, вы вернетесь к первоначальной проблеме.

Вы можете решить эту проблему, имея своего рода онлайн / динамический ЦС, где серверы будут запрашивать и выдавать сертификат динамически на основе чего-то, что они могут динамически доказать этому ЦС (чтобы доказать, что это один из ваших серверов, возможно, на основенекоторый параметр конфигурации, известный обоим), а затем клиент доверяет этому ЦС, но это более сложный сценарий.

0 голосов
/ 12 октября 2010

Для вашей заявленной цели защиты связи между двумя хостами, оба из которых находятся под вашим контролем, SSH будет лучшим решением.Вы можете сгенерировать пару ключей, которой поделились только с вашей другой машиной.Google "Java SSH" для множества вариантов.

0 голосов
/ 12 октября 2010

Почему? Это не безопасно, и кто будет доверять этому в любом случае? Почему вы не можете создать сертификат сервера для каждого развертывания в автономном режиме?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...