title: Difference between KeyStore and KeyManager/TrustManager
body: <p>What is the difference between using a KeyStore Object for the keystore and truststore; as opposed to using the KeyManager and TrustManager?</p>
  
  <p>Let me explain why I am asking.  I am working with RESTEasy and needed to make a REST call over HTTPS with SSL certificates.  I needed to augment how RESTEasy created the ClientRequest. Here is what I figured out initially:</p>
  
  <pre class="lang-java prettyprint-override"><code>public void afterPropertiesSet() throws Exception {
      Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank.");
      Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank.");
      Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank");
  
      // Set the keystore and truststore for mutual authentication
      createKeystore();
      createTruststore();
  
      if (getHttpClient() == null) {
          // Initialize HTTP Client
          initializeHttpClient();
      }
  
      Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization");
  }
  
  public ClientRequest createClientRequest(String uri) throws URISyntaxException {
      ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient());
      ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri));
      return fac.createRequest(uri);
  }
  
  private void createTruststore() throws KeyStoreException, FileNotFoundException, IOException,
          NoSuchAlgorithmException, CertificateException {
  
      String truststoreFilePath = getTruststorePath() + getTruststoreName();
  
      KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
      InputStream truststoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath);
      truststore.load(truststoreInput, getTruststorePassword().toCharArray());
  }
  
  private void createKeystore() throws KeyStoreException, FileNotFoundException, IOException,
          NoSuchAlgorithmException, CertificateException {
  
      String keystoreFilePath = getKeystorePath() + getKeystoreName();
      KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
      InputStream keystoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath);
      keystore.load(keystoreInput, getKeystorePassword().toCharArray());
  }
  
  /**
   * Initializes the HTTP Client
   * 
   * @throws KeyStoreException
   * @throws NoSuchAlgorithmException
   * @throws UnrecoverableKeyException
   * @throws KeyManagementException
   */
  private void initializeHttpClient() throws KeyManagementException, UnrecoverableKeyException,
          NoSuchAlgorithmException, KeyStoreException {
  
      // Register https and http with scheme registry
      SchemeRegistry schemeRegistry = new SchemeRegistry();
      SSLSocketFactory sslSocketFactory = new SSLSocketFactory(getKeystore(), getKeystorePassword(), getTrustStore());
      schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory()));
      schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory));
  
      // Set connection params
      HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout);
      HttpConnectionParams.setSoTimeout(httpParameters, readTimeout);
      HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true);
  
      // Create Connection Manager
      PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry);
      clientManager.setMaxTotal(maxTotalConnections);
      clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost);
  
      httpClient = new DefaultHttpClient(clientManager, httpParameters);
  }
  </code></pre>
  
  <p>I ran into a problem with the Peer Certificates and kept getting an exception:  </p>
  
  <blockquote>
    <p>javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated</p>
  </blockquote>
  
  <p>I then searched around and found articles/blogs about setting up the HttpClient but using TrustManager and KeyManager.  I refactored the code to do the following:</p>
  
  <pre class="lang-java prettyprint-override"><code>public void afterPropertiesSet() throws Exception {
      Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank.");
      Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank");
      Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank.");
      Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank");
  
      if (getHttpClient() == null) {
          // Initialize HTTP Client
          initializeHttpClient();
      }
  
      Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization");
  }
  
  public ClientRequest createClientRequest(String uri) throws URISyntaxException {
      ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient());
      ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri));
      return fac.createRequest(uri);
  }
  
  /**
   * Initializes the HTTP Client
   * 
   * @throws KeyStoreException
   * @throws NoSuchAlgorithmException
   * @throws UnrecoverableKeyException
   * @throws KeyManagementException
   */
  private void initializeHttpClient() throws Exception {
  
      if (isCheckPeerCertificates()) {
          checkPeerCerts();
      }
  
      // Create Trust and Key Managers
      // Use TrustManager and KeyManager instead of KeyStore
      TrustManager[] trustManagers = getTrustManagers(getTruststorePassword());
      KeyManager[] keyManagers = getKeyManagers(getKeystorePassword());
  
      // Create SSL Context
      SSLContext ctx = SSLContext.getInstance("TLS");
      ctx.init(keyManagers, trustManagers, new SecureRandom());
  
      // Create SSL Factory
      SSLSocketFactory sslSocketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  
      // Register https and http with scheme registry
      SchemeRegistry schemeRegistry = new SchemeRegistry();
      schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory()));
      schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory));
  
      // Set connection params
      HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout);
      HttpConnectionParams.setSoTimeout(httpParameters, readTimeout);
      HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true);
  
      // Create Connection Manager
      PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry);
      clientManager.setMaxTotal(maxTotalConnections);
      clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost);
  
      httpClient = new DefaultHttpClient(clientManager, httpParameters);
  }
  
  private TrustManager[] getTrustManagers(String trustStorePassword) throws Exception {
      String truststoreFilePath = getTruststorePath() + getTruststoreName();
      InputStream trustStoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath);
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
      trustStore.load(trustStoreInput, trustStorePassword.toCharArray());
      TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmfactory.init(trustStore);
      return tmfactory.getTrustManagers();
  }
  
  private KeyManager[] getKeyManagers(String keyStorePassword) throws Exception {
      String keystoreFilePath = getKeystorePath() + getKeystoreName();
      InputStream keyStoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath);
      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
      keyStore.load(keyStoreInput, keyStorePassword.toCharArray());
      KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
      kmfactory.init(keyStore, keyStorePassword.toCharArray());
      return kmfactory.getKeyManagers();
  }
  </code></pre>
  
  <p>The second code works just fine.  So, what is the a difference between the 2 types of usages?</p>