Sunday, July 18, 2010

SSL, KeyStore and Key password

SSL server socket can be created by:
  • Calling SSLServerSocketFactory: SSLServerSocketFactory.getDefault()
    The default implementation can be specified in $JREHOME/lib/security/java.security by
    ssl.ServerSocketFactory.provider, but by default, it is not specified, instead, a internal
    implementation is used( JSSE: com.sun.net.ssl.internal.ssl.SSLServerSocketFactoryImpl)

    When this (default) implementation is used, you must specify:
    • keystore using javax.net.ssl.keyStore, if not, an empty keystore object will be managed by the KeyManager
    • keystore passwrod using javax.net.ssl.keyStorePassword
      Notice here,for the getDefault() will lead to the default SSLContext, default
      KeyManager, default TrustManager. And the most important thing is, you can only
      specify the keystore password, there is no way to specify the keys' password
      the system properties.


      For the SSL Socket created by the calling of getDefault(),the specified Keystore and the keys in the keystore must have the same password.

      Only the default implementation and is used, requires the keystore password and the keys' password must be the same.
  • Using customized SSLContext to create SSLSocket
For example:


try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(secureKeyStore.asInputStream(keystorePath), secureKeyStore
.getKeyStorePassword());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, secureKeyStore.getCertificatePassword());
serverContext = SSLContext.getInstance(PROTOCOL);
serverContext.init(kmf.getKeyManagers(), SecureTrustManagerFactory
.getTrustManagers(), null);
} catch (Exception e) {
e.printStackTrace();
throw new Error("Failed to initialize the server-side SSLContext",
e);
}

In the code above, we may notice, the kmf.init(KeyStore keystore, char[] pass) method accepts two arguments, the second one specifies the password for the key(s) or certificate(s).

Note that only one password is used in this method, so the keystore must use the same
password for all the private keys it stores, and there is no requirements this password must
be the same as the keystore password( but the default implementation requires this).

If the keys in the keystore have different password, the JSSE KeyManagerFactory.init() mehtod will throw UnrecoverableKeyException. Some other implementation may just return the matched key(s), but JSSE does not.

No comments:

Post a Comment