2010-10-11 25 views
0

是否有简单的方法来dinamic生成不受信任的SSL证书没有域,并将其应用到服务器套接字 - 所有的代码,没有命令行或额外的文件?如何简单地生成SSL证书和ServerSocket形式的Java代码

目的是两台主机之间的安全连接只知道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(); 
    } 

} 

回答

2

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

这对测试很有用,但是这个不会使您的应用程序安全。一般来说,没有远程方认证的加密是不安全的。您可以像远程聚会一样“秘密地”交换信息,但是如果您未验证其身份,则您不确定您的秘密是否会提供给目标收件人。

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

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

你可以通过某种在线/动态CA来解决这个问题,服务器根据他们可以动态证明给CA的某些内容来动态地请求和颁发证书(以证明它们是你的服务器之一,可能基于两者都知道的一些配置参数),然后让客户端相信CA,但这是一个更复杂的场景。

0

为什么?这是不安全的,谁又会信任它?为什么不能为每个部署脱机创建服务器证书?

+0

这是用自签名证书的安全数据,据我所知应用程序可以动态生成它 – jlmfao 2010-10-12 00:03:07

+0

不,他们不能。客户端必须信任服务器的证书。在Java中,这意味着将其导入到客户端的信任库中。 – EJP 2010-10-12 00:21:11

1

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