Using multiple SSL client certificates in Java with the same host

前端 未结 3 1196
孤城傲影
孤城傲影 2020-12-29 15:42

In my Java application, I need to connect to the same host using SSL, but using a different certificate each time. The reason I need to use different certificates is that t

相关标签:
3条回答
  • 2020-12-29 15:53

    SSL can provide hints to the client about which certificate to present. This might allow you to use one key store with multiple identities in it, but, unfortunately, most servers don't use this hinting feature. So, it will be more robust if you specify the client certificate to use on for each connection.

    Here is sample code to set up one SSLContext with specified identity and trust stores. You can repeat these steps to create multiple contexts, one for each client certificate you want to use. Each SSLContext would probably use the same trust store, but a different identity store (containing the single client key entry to be used in that context).

    Initialize the contexts that you will need one time, and reuse the the correct one for each connection. If you are making multiple connections, this will allow you to take advantage of SSL sessions.

    KeyManagerFactory kmf = 
      KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(identityStore, password);
    TrustManagerFactory tmf =
      TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    

    Later, you can create a socket directly:

    SSLSocketFactory factory = ctx.getSocketFactory();
    Socket socket = factory.createSocket(host, port);
    

    Or, if you are using the URL class, you can specify the SSLSocketFactory to use when making HTTPS requests:

    HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
    con.setSSLSocketFactory(ctx.getSocketFactory());
    

    Java 6 has some additional API that makes it easier to configure sockets according to your preferences for cipher suites, etc.

    0 讨论(0)
  • 2020-12-29 16:02

    Implementations may have changed a lot since the question was asked. My understanding is that the server will send trusted issues to the client:

    Found trusted certificate:
    [
    [
      Version: V3
      Subject: CN=localhost, OU=Spring, O=Pivotal, L=Holualoa, ST=HI, C=US
      Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
    

    Then the client will receive a CertificateRequest:

    *** CertificateRequest
    Cert Types: RSA, DSS, ECDSA
    Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
    Cert Authorities:
    <CN=localhost, OU=Spring, O=Pivotal, L=Holualoa, ST=HI, C=US>
    

    Then the client will scan its local keystore with issuers:

    Set<X500Principal> certIssuers =
                            credentials.getIssuerX500Principals();
    for (int i = 0; i < x500Issuers.length; i++) {
        if (certIssuers.contains(issuers[i])) {
            aliases.add(alias);
            if (debug != null && Debug.isOn("keymanager")) {
                System.out.println("matching alias: " + alias);
            }
            break;
        }
    

    If found, it will use that certificate.

    0 讨论(0)
  • 2020-12-29 16:07

    There is a solution here for dynamically choosing the client certificate used for SSL Authentication from an Axis Client.

    0 讨论(0)
提交回复
热议问题