title: How can I have multiple SSL certificates for a Java server
body: <p>I have an in-house HTTP server written in Java; full source code at my disposal. The HTTP server can configure any number of web sites, each of which will have a separate listen socket created with:</p>
  
  <pre><code>skt=SSLServerSocketFactory.getDefault().createServerSocket(prt,bcklog,adr);
  </code></pre>
  
  <p>Using a standard key store created with the Java keytool, I cannot for the life of me work out how to get different certificates associated with different listen sockets so that each configured web site has it's own certificate.</p>
  
  <p>I'm in a time pinch for this now, so some code samples that illustrate would be most appreciated.  But as much I would appreciate any good overview on how JSSE hangs together in this regard (I have searched Sun's JSSE doco until my brain hurts (literally; though it might be as much caffeine withdrawal)).</p>
  
  <p><strong>Edit</strong></p>
  
  <p>Is there no simple way to use the alias to associate the server certificates in a key store with the listen sockets? So that:</p>
  
  <ul>
  <li>The customer has one key store to manage for all certificates, and</li>
  <li>There is no need to fiddle around with multiple key stores, etc.</li>
  </ul>
  
  <p>I was getting the impression (earlier this afternoon) that I could write a simple KeyManager, with only <code>chooseServerAlias(...)</code> returning non-null, that being the name of the alias I wanted - anyone have any thoughts on that line of reasoning?</p>
  
  <p><strong>Solution</strong></p>
  
  <p>The solution I used, built from <a href="https://stackoverflow.com/users/3474/sylvarking">slyvarking</a>'s answer was to create a temporary key store and populate it with the desired key/cert extracted from the singular external key store.  Code follows for any who are interested (svrctfals is my "server certificate alias" value):</p>
  
  <pre><code>    SSLServerSocketFactory              ssf;                                    // server socket factory
      SSLServerSocket                     skt;                                    // server socket
  
      // LOAD EXTERNAL KEY STORE
      KeyStore mstkst;
      try {
          String   kstfil=GlobalSettings.getString("javax.net.ssl.keyStore"        ,System.getProperty("javax.net.ssl.keyStore"        ,""));
          String   ksttyp=GlobalSettings.getString("javax.net.ssl.keyStoreType"    ,System.getProperty("javax.net.ssl.keyStoreType"    ,"jks"));
          char[]   kstpwd=GlobalSettings.getString("javax.net.ssl.keyStorePassword",System.getProperty("javax.net.ssl.keyStorePassword","")).toCharArray();
  
          mstkst=KeyStore.getInstance(ksttyp);
          mstkst.load(new FileInputStream(kstfil),kstpwd);
          }
      catch(java.security.GeneralSecurityException thr) {
          throw new IOException("Cannot load keystore ("+thr+")");
          }
  
      // CREATE EPHEMERAL KEYSTORE FOR THIS SOCKET USING DESIRED CERTIFICATE
      try {
          SSLContext        ctx=SSLContext.getInstance("TLS");
          KeyManagerFactory kmf=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
          KeyStore          sktkst;
          char[]            blkpwd=new char[0];
  
          sktkst=KeyStore.getInstance("jks");
          sktkst.load(null,blkpwd);
          sktkst.setKeyEntry(svrctfals,mstkst.getKey(svrctfals,blkpwd),blkpwd,mstkst.getCertificateChain(svrctfals));
          kmf.init(sktkst,blkpwd);
          ctx.init(kmf.getKeyManagers(),null,null);
          ssf=ctx.getServerSocketFactory();
          }
      catch(java.security.GeneralSecurityException thr) {
          throw new IOException("Cannot create secure socket ("+thr+")");
          }
  
      // CREATE AND INITIALIZE SERVER SOCKET
      skt=(SSLServerSocket)ssf.createServerSocket(prt,bcklog,adr);
      ...
      return skt;
  </code></pre>