简体   繁体   中英

How java SSLSocketFactory choose the server certificate and private key during SSL from keystore

I have a Jetty server where I'm opening opening more than one SSL ports and setting the SslContextFactory where I am pointing it to my custom keystore in which I have certificates for all the SSL ports.

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;       
}

This SslContextFactory I'm setting in ServerConnector SslConnectionFactory . And I have multiple ServerConnectors and all have the same SslContextFactory .

My question is as I have multiple PKI-cert and private key in custom key store. How SslConnectionFactory will know which PKI-cert and private key belongs to which SSL port?

SSL certificate is related to some domain/hostname+port of a server. So the domain/hostname+port data is present in the certificate. When you would make a connection, the SslConnectionFactory will look if a certificate is present for the particular domain/hostname+port and if it is present it will use that certificate and the private key related to the same for doing handshake.

Remember,by default SSL certificates for domain name know that the port is 443. Similarly, it would work for different ports.

The certificate and key used for an SSLContext server is selected by the KeyManager it is initialized with.

If you want to manually select the certificate and/or key you can implement your own KeyManager and place your code in:

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

PrivateKey getPrivateKey(String alias)

The first method allows you to specify which alias identifies the certificate and the second gets the alias defined in the first method and loads the private key.

If you implement the first method in a way that it returns the alias of the key/certificate in the key store you can delegate the second to an existing KeyManager instance.

The resulting code will look like this:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM