我有一个Jetty服务器,我打开多个SSL端口并设置SslContextFactory
我将其指向我的自定义密钥库,我在其中拥有所有SSL端口的证书。
public static SslContextFactory getCustomSSLContextFactory() throws IOException {
KeyStoreInfo keyStoreInfo = KeyStoreInfo.getInstance();
SslContextFactory sslContextFactory = new SslContextFactory(mycustomkeystorepath);
sslContextFactory.setKeyStorePassword(mykeystorepassword);
sslContextFactory.setKeyStoreType(keystoretype);
sslContextFactory.setTrustStorePath(defaultcatruststore);
sslContextFactory.setTrustStorePassword(password);
sslContextFactory.setTrustStoreType(truststoretype);
sslContextFactory.setNeedClientAuth(true);
return sslContextFactory;
}
此SslContextFactory
我在ServerConnector SslConnectionFactory
中进行了设置。我有多个ServerConnector,并且都具有相同的SslContextFactory
。
我的问题是我在自定义密钥库中有多个PKI-cert和私钥。 SslConnectionFactory
如何知道哪个PKI-cert和私钥属于哪个SSL端口?
答案 0 :(得分:1)
SSL证书与服务器的某些域/主机名+端口相关。因此,域/主机名+端口数据存在于证书中。当您建立连接时,SslConnectionFactory将查看特定域/主机名+端口是否存在证书,如果存在,它将使用该证书以及与之相关的私钥进行握手。
请记住,默认情况下,域名的SSL证书知道端口是443.同样,它适用于不同的端口。
答案 1 :(得分:1)
用于SSLContext
服务器的证书和密钥由初始化的KeyManager
选择。
如果您想手动选择证书和/或密钥,您可以实现自己的KeyManager并将代码放入:
String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
PrivateKey getPrivateKey(String alias)
第一种方法允许您指定哪个别名标识证书,第二种方法获取第一种方法中定义的别名并加载私钥。
如果以一种方式实现第一种方法,它返回密钥库中密钥/证书的别名,则可以将第二种方法委托给现有的KeyManager实例。
结果代码如下所示:
String algorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
keyManagerFactory.init(keyStore, "".toCharArray());
KeyManager[] defaultKeyManagers = keyManagerFactory.getKeyManagers();
KeyManager mykm = new MyKeyManager((X509KeyManager) defaultKeyManagers[0]);
sslContext.init(new KeyManager[] { mykm } , trustManagerFactory.getTrustManagers(), new SecureRandom());
static class MyKeyManager implements X509KeyManager {
final X509KeyManager delegate;
public KeyManager(X509KeyManager delegate) {
this.delegate = delegate;
}
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
delegate.chooseClientAlias(keyType, issuers, socket);
}
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
... implement your code here
}
public X509Certificate[] getCertificateChain(String alias) {
return delegate.getCertificateChain(alias);
}
public String[] getServerAliases(String keyType, Principal[] issuers) {
return delegate.getServerAliases(keyType, issuers);
}
public String[] getClientAliases(String keyType, Principal[] issuers) {
return delegate.getClientAliases(keyType, issuers);
}
public PrivateKey getPrivateKey(String alias) {
return delegate.getPrivateKey(alias);
}
}