java - Java代码如何简单生成SSL证书和ServerSocket

标签 java ssl ssl-certificate

是否有简单的方法动态生成不带域的不受信任的 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();
    }

}

最佳答案

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

这对测试很有用,但这不会使您的应用程序安全。一般来说,未经远程方身份验证的加密是不安全的。您可以根据需要与远程方“ secret 地”交换信息,但如果您没有验证其身份,您就不能真正确定您的 secret 是否已提供给预期的接收者。

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

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

您可以通过某种在线/动态 CA 来解决此问题,其中服务器将根据它们可以动态向该 CA 证明的内容(以证明它们是您的服务器之一,可能基于一些双方都知道的配置参数),然后让客户端信任那个 CA,但这是一个更复杂的场景。

关于java - Java代码如何简单生成SSL证书和ServerSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3910745/

相关文章:

php - Gmail fsockopen() : SSL operation failed error with Codeigniter and XAMPP

ssl - docker 证书的最佳实践

ruby-on-rails - 我可以使用 Heroku Piggyback SSL 登录主网站吗?

android - 测试 SSL 攻击 - 可以在 SSLException 之后提取服务器证书吗?

cryptography - 将 X.509 证书从十六进制格式转换为 .cer 格式

java - 使用 MySQL 的 SimpleJdbcInsert

java - 从不同位置加载属性

ssl - SSL证书签发速度是什么意思?

java - jsf 2.0 表达式语言括号不起作用

java - DES 蛮力(学术)