What is Keystore?
Solution 1:
Keystore in Java can refer to three things, depending on the context. (They're all closely related but subtly different.)
A keystore can be a repository where private keys, certificates and symmetric keys can be stored. This is typically a file, but the storage can also be handled in different ways (e.g. cryptographic token or using the OS's own mechanism.)
-
KeyStore
is also a class which is part of the standard API. It is essentially a way to load, save and generally interact with one of the "physical" keystores as described above. AKeyStore
can also be purely in memory, if you just need the API abstraction for your application.How to load and handle such a
KeyStore
instance depends on the format of the keystore file (or other storage system) that backs it. Multiple formats are available. Some of the most common are JKS and PKCS#12 (.p12). -
"keystore" can also be used as the counterpart of "truststore". This is where it can get confusing, since both "keystore" and "truststore" are keystores, they're just used for different purposes. You can find more details in this answer. The keystore is used to initialise the key manager, whereas the truststore is used to initialise the trust manager. From the JSSE reference guide:
A
TrustManager
determines whether the remote authentication credentials (and thus the connection) should be trusted.A
KeyManager
determines which authentication credentials to send to the remote host.
Essentially, a keystore used as a truststore will contain a number of (CA) certificates that you're willing to trust: those are the trust anchors you are going to use to verify remote certificates you don't already know and trust. In contrast, a keystore used as a keystore will contain your own certificate and its private key: this is what you're going to use to authenticate yourself to a remote party (when required).
There is a default truststore bundled with the JRE (
/lib/security/cacerts
). There isn't a default keystore, since it's usually a more explicit step for the user.
In the context of SSL/TLS, a keystore (keystore used as a keystore) will be where a server stores its certificate and private key (or, when client-certificate authentication is used, where the client stores its certifcate and private key). A truststore (keystore used as a truststore) will be where the client stores the CA certificates of the CAs it is willing to trust, so as to be able to verify the server certificate when making a connection to an SSL/TLS server (similarly, on the server side, this is also where the CA certificates used to verify the client certificates are stored).
Typically, the error you're getting ("ValidatorException: PKIX path building failed
") happens when the certificate of the server you're connecting to cannot be verified using any certificate in the truststore you're using. You would generally need to have in your truststore either the server certificate directly in your truststore (which is only manageable on a small scale) or the CA certificate of the CA used to issue that server certificate (or one of the certificates in the chain it presents, when there is a chain).
Solution 2:
Simply speaking, to establish a connection to an SSL-endpoint, you have to trust its public certificate. To trust a certificate, either itself or the certificate of its issuer has to be in the keystore.
Think of the keystore as a set of folders or a database/repository which contains certificates. Physically, it is a file in the JRE (/lib/security/cacerts
).
This repository can be modified with the keytool
command that ships with the JRE. See this link for some common commands. Another way is to use the Certificate Dialog of the Java Control Panel (this is also installed with the JRE):