2010-10-11 16 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」提供了很多選項。