When tried to connect to Oracle Database 12c using 12.1.0.2 JDBC Thin driver, we are getting an exception. We are using TLSv1.2 with JKS certificates. But, we are unable to connect to the database successfully.
Exception in thread "main" java.sql.SQLRecoverableException: IO Error:
Received fatal alert: handshake_failure
Here are the steps to follow to configure the Oracle JDBC thin driver to connect to the Database using TLS v1.2 (assuming your Database configuration is correct).
Step 1: Apply patch for bug 19030178 (not needed starting in 12.2.0.1)
You will need to apply the patch for bug 19030178 which allows TLSv1.2. Note that the patch allows TLSv1.2 but doesn't enable it by default. So with the 12.1.0.2 patched driver you also need to set oracle.net.ssl_version='1.2'. This property can be set either as a system property (using -D) or through the datasource properties.
Step 2: Install JCE files
Without the Java Cryptography Extension (JCE) files, the strong cipher suites (for example TLS_RSA_WITH_AES_256_CBC_SHA256) won't be enabled. So whether you're using JDK7 or JDK8, you should install the JCE Unlimited Strength Jurisdiction Policy Files. These files can be found on the Oracle website.
Step 3: Always use the latest update of the JDK
Be sure to use the latest update of either JDK7 or JDK8 because bugs have been fixed that are required for TLSv1.2.
Step 4: Use JKS files instead of wallets
It looks like you have already done that but just for others to see: wallets are complicated to configure and use with the Oracle JDBC thin driver because they require extra jars and extra properties. JKS files on the other hand are supported natively in the JRE and, in my experience, have always worked nicely.
Step 5: When using JDK7, explicitly enable strong cipher suites
This step is not required when using JDK8. With JDK7, if you're using a strong cipher suite such as TLS_RSA_WITH_AES_256_CBC_SHA256, then you must enable it through the oracle.net.ssl_cipher_suites connection property.
Step 6: Debug with -Djavax.net.debug=all
Finally if you run into more issues, you can turn on tracing to find out what's going using -Djavax.net.debug=all.
==== EXAMPLE WITH JDK7 AND THE 12.1.0.2 PATCHED THIN DRIVER =====
java -Doracle.net.ssl_version='1.2' -Doracle.net.ssl_cipher_suites='(TLS_RSA_WITH_AES_256_CBC_SHA256)' -Doracle.net.ssl_server_dn_match='true' -Djavax.net.ssl.trustStore='truststore.jks' -Djavax.net.ssl.trustStorePassword='welcome1' -Djavax.net.ssl.keyStore='keystore.jks' -Djavax.net.ssl.keyStorePassword='welcome1' JDBCTest 'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=host)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=myservice))(security=(ssl_server_cert_dn="CN=name,O=org,L=city,ST=state,C=country")))' 'pdb1' 'welcome1'
==== EXAMPLE WITH JDK8 AND THE 12.1.0.2 PATCHED THIN DRIVER =====
java -Doracle.net.ssl_version='1.2' -Doracle.net.ssl_server_dn_match='true' -Djavax.net.ssl.trustStore='truststore.jks' -Djavax.net.ssl.trustStorePassword='welcome1' -Djavax.net.ssl.keyStore='keystore.jks' -Djavax.net.ssl.keyStorePassword='welcome1' JDBCTest 'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=host)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=myservice))(security=(ssl_server_cert_dn="CN=name,O=org,L=city,ST=state,C=country")))' 'pdb1' 'welcome1'