Class KeyStore has a method called setCertificateEntry(alias, certificate). Most client examples I see use "ca" as the alias name. Is the server asking for "ca" automatically during the client-server handshake? What really would happen if I use "abc" instead of "ca?" Regards.
The alias is really just a name that is local to the keystore you are using. It is what identifies the entry in the keystore, so you can't re-use it for two entries, but it can be whatever you like (although I must admit I have never tried with non-ASCII characters, and the official truststore only uses lower case letters or numbers).
The documentation also says:
Whether aliases are case sensitive is implementation dependent. In order to avoid problems, it is recommended not to use aliases in a KeyStore that only differ in case.
Some keystore implementations and formats might have more constraints or use that name differently. For example, the WINDOWS-ROOT keystore (which is a front-end for the Windows native store) uses Windows's "friendly name" as the alias, which is unfortunately not unique in the Windows certificate store, so some certificates from the native store may be hidden and not usable (it's a map from alias to entry, loading a new entry with the same name replaces the other one). However, this shouldn't be a concern on Android, of course.
If you're building a keystore that you'll use as a truststore, which is likely to contain a number of CAs, calling one "ca" would make it difficult to identify them later on. (This is mostly an administrative problem to be able to find manually which cert is where.)
If you look at the default truststore, you'll get aliases with names the resemble the Subject DN of these CA certificates, for example "verisignclass1g2ca".
Having an identifier you can remember is generally more important for keystores that are used as keystores (as opposed to truststores) and which contain multiple private key entries, since this can help you configure your application to use a particular certificate to identify itself.
Related
I'm implementing a mutual authentication with a web server in Java on Windows.
I have a certificate on a SmartCard which is supposed to be used to authenticate me (or other user).
So far I've figured out that I can access the certificates using Windows-MY key store.
I do it like that:
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.init(null, null);
This works. I can see all certificates inside keystoreSpi (in debugger). One of them is the one which I need to use - I confirmed that.
The problem is as follows:
KeyStore api allows me to get a certificate only by using it's alias. e.g. keyStore.getCertificate("alias") or keystore.getCertificateChain("alias")
I noticed that there are multiple different certificates with the same alias in this keystore. I cannot change the aliases. I just physicaly got the smartcard with given certificates.
When I call one of the mentioned methods, keystore returns just the first certificate in the list with given alias. (generally, in the implementation there is a map where aliases are it's keys, so all duplicated aliases are ignored).
Unfortunately first certificate's purpose is "email encryption", etc. The second certificate's purpose is "SmartCard Logon" and this one I need to use. I confirmed that by going into debugger and manually hacking the list of certificates.
The question is: how do I get a proper certificate using the API (eg. the second one) when there are duplicated aliases?
If this can be done by external libraries, I can opt for that.
More details which may be useful:
I use KeyStore, then create KeyStoreManager.
I initialize SSLContext with given keyStoreManager sslContext.init(keyManagerFactory.getKeyManagers(), ...)
I create HttpsUrlConnection with given ssl context, which is my objective.
This has been fixed a while ago. Just update to a recent JRE. For more information see here: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6483657
I recently joined a project that has an application running in Tomcat that uses a single file as both the KeyStore and the TrustStore. In other words, it includes both entries of types trustedCertEntry and PrivateKeyEntry.
While upgrading from Tomcat 8.5.6 to 8.5.20, I realized catalina.out was giving me
java.lang.IllegalArgumentException: java.security.KeyStoreException: Cannot store non-PrivateKeys
The solution was to make to remove the trustedCertEntry entries from the keystore.
To me, this seems fairly obvious that you would want to keep these separate. My question is, are there any possible security consequences to using the same file as a keystore and truststore? If so, why does Java (or SSL) allow these to be kept in the same file?
SSL and TLS are interoperable protocols; by IETF policy and tradition they say nothing about storage of anything and everything at either or any endpoint. "That's a local matter."
Java historically used one file format (JKS) for both TrustedCert's and PrivateKey's, not only for SSL/TLS but for all public-key crypto (and optionally with JCEKS some symmetric crypto also), and Java9 is switching to PKCS12 for both. Using the same format doesn't mean you must use the same file, and I would say it's preferable to use separate files, but I don't see an actual security problem in using a single file as long as you keep any file containing a privatekey restricted to one system, or as few systems as absolutely necessary, plus appropriate backup; however that's not really a programming Q and you might try for better answers on security.SX.
Tomcat 8.5 sorta-kinda combines the previously separate and (often confusingly) different config for Java-JSSE and APR=OpenSSL stacks, and I believe this restriction that the keystore can only contain PrivateKey's is a result of that change.
I recently had to add my corporate root CA (based on AD CS) into the JRE default truststore (the $JAVA_HOME/lib/security/cacerts file). I then discovered (as I am new to this) that the default password is changeit.
I found various posts explaining how to change it but there are two questions I can't find answers to:
Is keeping the default password a security risk? I guess an attacker could then import compromised certificates so clients trust them
What are the impacts of changing this truststore password? I also guess the JRE can look for root CA inside because it knows the default password. Once changed, will it have to be provided somewhere (config file, ...)?
We mainly use Java on Windows for websites which have applets, so we don't start anything from the command line (on which I know the password can be provided).
Regarding your second question, there are system properties to specify passwords for default trust store and default key store. The one for the trust store is:
javax.net.ssl.trustStorePassword
I found that information at https://stackoverflow.com/a/5871352/5629418
If the attacker can read your Java system properties, either in a config file or by running a Java program, then changing the password will be mostly futile though.
Regarding your second question: "What are the impacts of changing this truststore password?"
One of the implications of changing of that password is that the memory bits holding the new password value is better to allocate and to store somewhere for their following retrievals, provisions for the corresponding accesses. And if that password is not stored, it is better to have a procedure about how to restore it then.
That article contains the code for changing such password:
thetechawesomeness.ideasmatter.info
A keystore (no matter if it's used for "keystores" or "truststores") is initialized after creation using the load() method. One version expects an InputStream corresponding to the keystore file, and the password to decrypt the file. Providing the password to the method programmatically seems strange to me.
For example, a server uses a keystore to store its private keys and the associated certificates. The information present in the keystore is sensible so it is protected by a password. What are the problems of passing the password to the load() method programmatically? What is the best practice?
The other example, but for now concerning truststores. The client has a truststore where it stores the certificates of trusted CAs. As I understand it, the truststore doesn't contain the certificate of the server but only the certificates of the CAs that allow verifying the server's certificate. One truststore example I see is the one present with the JRE (in the security folder - cacerts). By looking at the configuration, I can see it is protected by the default password changeit. I understand that a truststore is implemented using a keystore, so it has (or maybe it's optional?) to be encrypted using a password. But, since truststores generally store public information (trusted CA's certificates) in the file, why changing the password is recommended?
Thanks
Providing the password to the method programmatically seems strange to
me.
I'm not sure why this would be strange. The application will need to be able to get hold of the content of the keystore at one point or another. The password will need to be passed to it, somehow. Passing it to the load() method doesn't make less sense than other solutions (avoid hard-coding, of course). Alternatively, you can use the method that uses a callback instead. If you don't think that's suitable, you can use a PKCS#11 provider and a hardware token (although you'll still need to enter the password/PIN somewhere) or use something like the Apple KeychainStore (where the password isn't used, but the OS keychain service takes care of that).
Regarding the truststore, there are in fact two passwords in use. They can be different, when using the JKS format. One protects the keystore itself, and one protects access to the private entries (getKey). In this case, the keystore password is used to prevent unauthorised parties from altering the truststore (and adding their own CA or server certificates).
Is there a security issue when using the same keystore for the trust store (certificates used for authenticating clients) and server store (private keys used by the server)? I ask this because I know that there is a recommendation to have two separate files (and I wonder why this is).
I know that there is a recommendation to have two separate files (for the trust store and the server store)
The reason for such a recommendation is that you typically store only public keys and the related certificates of trusted CAs in the truststore, while the keystore is meant to store private-keys and the associated public keys (along with the related certificates).
When you start managing both as a single file, it is quite possible for any agent (a user or even application code) that has knowledge of the truststore password to read and modify the private keys of the keystore as well. This is not what you want, for private keys ought to be private by nature, and known only to a single entity (the one that owns the key).
Likewise, it is also possible for an agent to modify the truststore through the knowledge of the keystore password, to add certificates to the truststore. On it's own, this may appear benign, but usually multiple clients can use the same truststore (like the cacerts file of the JRE), resulting in the scenario where one agent can poison the trust relationship (by adding the certificate of a malicious CA into the truststore) between a client and a server.
In reality, the recommendation is more of a defense-in-depth practice, unless your agents aren't trustworthy (in which case you ought to be adopting several other practices).
There is one security concern, but I think most of the reason for the recommendation is a logical separation of responsibilities. From Keystores and Truststores:
Using two different files instead of a single keystore file provides for a cleaner separation of the logical distinction between your own certificates (and corresponding private keys) and others' certificates. You could provide more protection for your private keys if you store them in a keystore with restricted access, while providing the trusted certificates in a more publicly accessible keystore if needed.
The key security point here is that by separating the trusted (public) certificates from your own certificates that contain your private keys, you can use whatever level of restriction you deem necessary to protect your own private keys, while keeping trusted certificates public.