Author |
Topic: SSL/TLS Error Database -- Loading KeyStore |
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
SSL/TLS Error Database -- Loading KeyStore |
What is the keystore?
A keystore is the place where key entries are stored. It can be a file or a hardware device.
Generally speaking, keystore information can be grouped into two different categories: key entries and trusted certificate entries. A key entry consists of an entity's identity and its private key, and can be used for a variety of cryptographic purposes. In contrast, a trusted certificate entry only contains a public key in addition to the entity's identity. Thus, a trusted certificate entry can not be used where a private key is required, such as in a javax.net.ssl.KeyManager. In the JDK implementation of "JKS", a keystore may contain both key entries and trusted certificate entries.
There are two different passwords: keystore password and key password. The former is associated with the container (keystore) while the latter is associated with a specific key entry (key).
Keystore password is usually not required to open a key store unless you want to manage (modify/delete/add entry) it.
While accessing trusted certificate entries does not needs password since they are public in general sense; accessing key entries needs the key password for each of them.
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #1: KeyStore type is wrong |
String keystore_type = KeyStore.getDefaultType(); // "JKS"
try{
KeyStore ks = KeyStore.getInstance(keytore_type);
}catch(Exception e){
e.printStackTrace();
}
By default, the KeyStore type is defined and retrieved from the value of 'keystore.typ' in file
$JAVA_HOME/lib/security/java.security
The value is usually 'JKS' for Sun JRE. You can change it for different type of keystore, e.g. PKCS11, in the file or in your code by property setting :
System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
If KeyStore type you specified was not supported, you would most likely see something like this:
java.security.KeyStoreException: PKCS11 not found
at java.security.KeyStore.getInstance(Unknown Source)
at com.rli.slapd.server.bio.LDAPListenerSSL.getKeyManagers(LDAPListenerSSL.java:278)
at com.rli.slapd.server.bio.LDAPListenerSSL.getServerSocketFactory(LDAPListenerSSL.java:191)
at com.rli.slapd.server.bio.LDAPListenerSSL.run(LDAPListenerSSL.java:52)
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #2: KeyStore password is wrong |
char[] keystore_password = "KEYSTORE_PASSWORD".toCharArray();
try{
ks.load(new FileInputStream("path_to_your_keystore"), keystore_password);
}catch(Exception e){
e.printStackTrace();
}
If you guessed the keystore password wrong, you would most likely see something like this:
java.io.IOException: Keystore was tampered with, or password was incorrect
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #3: Key password is wrong |
String algorithm = KeyManagerFactory.getDefaultAlgorithm(); // "SunX509"
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
char[] key_password = "KEY_PASSWORD".toCharArray();
try{
kmf.init(ks, key_password);
}catch(Exception e){
e.printStackTrace();
}
If you guessed the key password wrong, you would most likely see something like this:
java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(Unknown Source)
at sun.security.provider.JavaKeyStore.engineGetKey(Unknown Source)
at java.security.KeyStore.getKey(Unknown Source)
at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.<init>(Unknown Source)
at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(Unknown Source)
at javax.net.ssl.KeyManagerFactory.init(Unknown Source)
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #4: Keystore is loaded but it's untrusted |
If your server is running on a keystore with certificate trusted by well-known root Certificate Authorities (CA) like VeriSign, your client's applications should recognize and trust your server's certificate quite smoothly. If your server's certificate is trusted only by intermediate Certificate Authorities or even self-signed, your client's applications have to manually decided whether or not to trust your server's certificate.
If the client rejected your certificate, you would see something like this:
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #5: Keystore is loaded but it's not bearing the hostname |
If your server's certificate is bearing a subject, say 'CN=ServerB,DC=myCompany,DC=com', that is different from the hostname of the machine, say 'ServerA', on which your server is running, you might have troubles in convincing your clients that the server is a genuine one. It's up to your clients to trust it or not.
For clients using Sun JDK SSL library, for example, the hostname unmatched certificate is acceptable.
For clients using JDNI StartTLS library, for example, the hostname unmatched certificate is NOT acceptable and the following exception is, on client side, thrown:
javax.net.ssl.SSLPeerUnverifiedException: hostname of the server 'ServerA'
does not match the hostname in the server's certificate.
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.verify(StartTlsResponseImpl.java:437)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:216)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:161)
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:210)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.verify(StartTlsResponseImpl.java:416)
... 3 more
|
|
|
|
|
|
|
authen member offline |
|
posts: |
56 |
joined: |
06/05/2006 |
from: |
San Diego, CA |
|
|
|
|
|
Error #6: Keystore is loaded but it's not bearing appropriate rights |
If your server's certificate does not have the right to run service. It's up to your client applications to trust it or not.
For clients using Sun JDK SSL library, for example, the certificate is going to be rejected and the following exception is, on client side, expected:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Extended key usage
does not permit use for TLS server authentication
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1522)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:180)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:861)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:111)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:509)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:447)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1034)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1061)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1045)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.startHandshake(StartTlsResponseImpl.java:344)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:208)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:161)
at sun.security.validator.EndEntityChecker.checkTLSServer(EndEntityChecker.java:252)
at sun.security.validator.EndEntityChecker.check(EndEntityChecker.java:117)
at sun.security.validator.Validator.validate(Validator.java:221)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:199)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:239)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:840)
On server side, you will see something like this:
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
|
|
|
|
|
|
|
|