2012-09-11 110 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