java - java SSLSocketFactory如何在SSL期间从 keystore 选择服务器证书和私钥

标签 java ssl keystore embedded-jetty ports

我有一台 Jetty 服务器,在其中打开多个 SSL 端口并设置 SslContextFactory,将其指向我的自定义 keystore ,其中我拥有所有 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;       
}

我在 ServerConnector SslConnectionFactory 中设置此 SslContextFactory。我有多个 ServerConnector,并且都具有相同的 SslContextFactory

我的问题是因为我在自定义 key 存储中有多个 PKI 证书和私钥。 SslConnectionFactory 如何知道哪个 PKI 证书和私钥属于哪个 SSL 端口?

最佳答案

用于 SSLContext 服务器的证书和 key 由 KeyManager 选择它是用 初始化的。

如果您想手动选择证书和/或 key ,您可以实现自己的 KeyManager 并将代码放入:

String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)

PrivateKey getPrivateKey(String alias)

第一个方法允许您指定标识证书的别名,第二个方法获取第一个方法中定义的别名并加载私钥。

如果您以返回 key 存储中 key /证书的别名的方式实现第一个方法,则可以将第二个方法委托(delegate)给现有的 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);
    }
}

关于java - java SSLSocketFactory如何在SSL期间从 keystore 选择服务器证书和私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50700662/

相关文章:

java拆分末尾缺少逗号

java - 如何修复我的偶数-奇数程序java代码,它写的是偶数或奇数,还有数字

ssl - Nginx - 仅在 SSL 证书存在时启用 SSL

java - 连接到远程服务器时,SocketException 默认 SSL 上下文为空

SSL 证书在 SOAPUI 中有效,但在 Jmeter2.13 中无效

java - 如何在 Java 项目中管理证书、信任库和 keystore key 文件

java - 如何在特定连接上使用不同的证书?

java 扫描器忽略 ^ Caret

java - 什么 Maven Artefact 持有 PowerMock.mockStaticPartial?

php - 从 HTTPS 到 HTTP 服务器的数据流