2012-09-11 109 views
8

我想在Java服務器應用程序中打開安全的偵聽套接字。我知道,推薦的方式做到這一點是隻要做到這一點:設置Java SSL ServerSocket使用的證書

SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 
ServerSocket ss = ssf.createServerSocket(443); 

但是這需要啓動Java時,服務器的證書傳遞給JVM。因爲這會使部署中的一些事情對我來說更加複雜,所以我寧願在運行時加載證書。

所以我有一個密鑰文件和一個密碼,我想要一個服務器套接字。我如何到達那裏?好吧,我閱讀文檔,我能找到的唯一方法是這樣的:

// these are my parameters for SSL encryption 
char[] keyPassword = "[email protected]!".toCharArray(); 
FileInputStream keyFile = new FileInputStream("ssl.key"); 

// init keystore 
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
keyStore.load(keyFile, keyPassword); 
// init KeyManagerFactory 
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
keyManagerFactory.init(keyStore, keyPassword); 
// init KeyManager 
KeyManager keyManagers[] = keyManagerFactory.getKeyManagers(); 
// init the SSL context 
SSLContext sslContext = SSLContext.getDefault(); 
sslContext.init(keyManagers, null, new SecureRandom()); 
// get the socket factory 
SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); 

// and finally, get the socket 
ServerSocket serverSocket = socketFactory.createServerSocket(443); 

而這甚至沒有任何錯誤處理。這真的很複雜嗎?有沒有更簡單的方法來做到這一點?

+1

這個問題是非常關於設置證書的問題。你的標題沒有強調(至今爲止的答案似乎錯過了這一點),所以我冒昧地改變它。如果你願意,請進一步改進標題。 –

+0

我認爲你到目前爲止提出的代碼是(a)可怕的,而(b)很可能是做到這一點的「正確」方式。 Java並不總是過於冗長,但是當它真的非常冗長時。 –

+0

如果您認爲這很複雜,請嘗試使用NIO進行操作。 –

回答

9

但是這需要在啓動java時將服務器的證書傳遞給JVM。

不,它不。只要你創建SSLServerSocket:

javax.net.ssl.keyStore ssl.key 
javax.net.ssl.keyStorePassword [email protected]! 

之前,你可以做設置這些系統屬性與System.setProperties()在命令行上

2

如果你看看代碼,你可以看到爲什麼它必然是複雜的。此代碼解耦SSL協議從實現:

  • 你的關鍵材料(KeyStore
  • 證書算法選擇和密鑰管理(KeyManager
  • 管理同行的信任規則(TrustManager)的源 - 這裏不使用
  • 安全隨機算法(SecureRandom
  • NIO或者套接字實現(SSLServerSocketFactory) - 可以使用SSLEngine的NIO

想象一下,如果您試圖達到相同的目標,您自己的實施將會是什麼樣子!

+0

但我使用默認的所有。應該有一個更直接的方法。 – Philipp

+0

@ Philipp沒有默認密鑰庫。 – EJP