如何简单地生成SSL证书和ServerSocket形式的Java代码

时间:2010-10-11 23:47:09

标签: java ssl ssl-certificate

有没有简单的方法来dinamic生成不带域的不受信任的ssl证书并将其applay到服务器套接字 - 所有这些都来自代码,没有命令行或其他文件?

目的是两个主机之间的安全连接,只知道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 个答案:

答案 0 :(得分:2)

您可以使用诸如BouncyCastle之类的库动态生成自签名证书(实质上,对于要自签名的证书,您使用与主题DN相同的颁发者DN并且您使用私有签名与证书的公钥对应的密钥)。然后,您需要将它放在KeyStore(至少在内存中,不一定在文件中)并从中构建SSLContext,以便能够构建SSLSocketFactory }。

这可用于测试,但不会使您的应用程序安全。一般而言,没有远程方认证的加密是不安全的。您可以根据需要“秘密”地与远程方交换信息,但如果您尚未验证其身份,则您不确定您的秘密是否已提供给目标收件人。

如果您的证书是动态生成的,那么在对该服务器进行任何调用之前,您需要找到一种让客户知道它确实是合法证书的方法。

一般的SSH方法(假设很少有人真正检查他们在第一次连接中获得的指纹 - 有些人实际上是在带外检查)是一种妥协,客户倾向于接受密钥(或多或少盲目)第一次,但如果它已经改变将被警告。您也可以实现这种处理X.509证书信任的方法,但如果每次重新启动服务器时重新生成新的自签名证书,则会回到最初的问题。

您可以通过某种在线/动态CA解决此问题,其中服务器将根据他们可以动态向CA证明的内容动态请求并颁发证书(以证明它们是您的服务器之一,也许基于两者都知道的一些配置参数,然后让客户端信任CA,但这是一个更复杂的场景。

答案 1 :(得分:1)

为了保证两个主机之间通信的安全目的,这两个主机都在您的控制之下,SSH将是一个更好的解决方案。您可以生成仅与其他计算机共享的密钥对。 Google“java ssh”提供了大量选项。

答案 2 :(得分:0)

为什么呢?它不安全,无论如何谁会相信它?为什么不能在每个部署中脱机创建服务器证书?