Search code examples
sslcertificatecertificate-authorityjava

Where is a CAcert's password used?


I am working with a vendor's appliance, and they use the default Java cacert for adding certs for allowing self-signed certs. When working on this process, I noticed that the cacert uses the default password changeit

For increased security, I would like to change the cacert password. Instructions are online. However, I am worried that once I change the password applications using cacert will stop functioning correctly.

I realize I don't really understand how Java is accessing cacert.

  • Does it need the cacert password?
  • Does anything need the cacert password?
  • Or do you only need the cacert password when adding or removing certs?

Solution

  • First of all, it's cacerts with an 's' at the end, not cacert. The password is only needed to modify the file, and that included adding or removing certificates. You don't need the password to use this file, though if you do supply a password it will be used to verify the integrity of the file.

    Java by default uses cacerts when verifying certificate chains and by default it does not use a password. Even though the JDK ships the cacerts file protected with the password changeit the Java runtime does not assume this. You can change the default behavior in a few ways, the simplest of which is to set the Java system property javax.net.ssl.trustStorePassword to the password. There is also a Java system property javax.net.ssl.trustStore that can be used to point to a file you want to use in place of cacerts. Using these tools you can, all optionally and independently:

    1. change the password on the system wide cacerts file.
    2. Tell Java to use the password to verify the integrity of the file.
    3. Tell Java to use a completely different file in place of cacerts.

    There is one obvious caveat that needs to be mentioned nevertheless. You say this is a vendor's appliance. That means the Java environment may have already been customized. Perhaps there is already code there that assumes the cacerts password is changeit. You did ask if anything uses the cacerts password.

    The above is really just a summary, the full story is documented in the JSSE Reference Guide. One particularly relevant section to your question I'll reproduce here:

    You can either implement this interface directly yourself or obtain one from a provider-based TrustManagerFactory (such as that supplied by the SunJSSE provider). You could also implement your own interface that delegates to a factory-generated trust manager. For example, you might do this to filter the resulting trust decisions and query an end-user through a graphical user interface.

    If a null KeyStore parameter is passed to the SunJSSE PKIX or SunX509 TrustManagerFactory, then the factory uses the following process to try to find trust material:

    1. If the javax.net.ssl.trustStore property is defined, then the TrustManagerFactory attempts to find a file using the file name specified by that system property, and uses that file for the KeyStore parameter. If the javax.net.ssl.trustStorePassword system property is also defined, then its value is used to check the integrity of the data in the truststore before opening it. If the javax.net.ssl.trustStore property is defined but the specified file does not exist, then a default TrustManager using an empty keystore is created.
    2. If the javax.net.ssl.trustStore system property was not specified, then:
      - if the file java-home/lib/security/jssecacerts exists, that file is used;
      - if the file java-home/lib/security/cacerts exists, that file is used;
      - if neither of these files exists, then the TLS cipher suite is anonymous, does not perform any authentication, and thus does not need a truststore.

    To know more about what java-home refers to, see Terms and Definitions.

    The factory looks for a file specified via the javax.net.ssl.trustStore Security Property or for the jssecacerts file before checking for a cacerts file. Therefore, you can provide a JSSE-specific set of trusted root certificates separate from ones that might be present in cacerts for code-signing purposes.