Saturday, July 3, 2021

Enabling SSL_DH_anon_WITH_3DES_EDE_CBC_SHA to work with TCPS/SSL for JDBC Thin Drvier

While testing out "Connect to the database through TCPS for SSL with Encryption Only" on 762286.1 encournted the following error.
java -Doracle.net.tns_admin=. JDBCSSLTester2 test2.properties
Start: Wed Jun 23 12:50:02 UTC 2021
SQL Exception occurred:
java.sql.SQLRecoverableException: IO Error: No appropriate protocol (protocol is disabled or cipher suites are inappropriate), Authentication lapse 0 ms.
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:894)
        at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:807)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:77)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:767)
        at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:450)
        at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:324)
        at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:234)
        at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:212)
        at JDBCSSLTester2.getConnection(JDBCSSLTester2.java:74)
        at JDBCSSLTester2.run(JDBCSSLTester2.java:34)
        at JDBCSSLTester2.main(JDBCSSLTester2.java:88)
Caused by: java.io.IOException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate), Authentication lapse 0 ms.
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:890)
        ... 10 more
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
        at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:101)
        at sun.security.ssl.TransportContext.kickstart(TransportContext.java:221)
        at sun.security.ssl.SSLEngineImpl.beginHandshake(SSLEngineImpl.java:98)
        at oracle.net.nt.SSLSocketChannel.doSSLHandshake(SSLSocketChannel.java:430)
        at oracle.net.nt.SSLSocketChannel.write(SSLSocketChannel.java:130)
        at oracle.net.ns.NIOPacket.writeToSocketChannel(NIOPacket.java:355)
        at oracle.net.ns.NIOConnectPacket.writeToSocketChannel(NIOConnectPacket.java:247)
        at oracle.net.ns.NSProtocolNIO.negotiateConnection(NSProtocolNIO.java:122)
        at oracle.net.ns.NSProtocol.connect(NSProtocol.java:364)
        at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1625)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:606)
        ... 10 more
Ended: Wed Jun 23 12:50:03 UTC 2021

This was intresting as the SQLPlus connection worked fine. So the issue is localized to java. For SSL_DH_anon_WITH_3DES_EDE_CBC_SHA to work with JDBC the cipher suite must be added to both sqlnet.ora and listener.ora (2621754.1, 1434966.1). As these were already in place in both those files missing chipher suite cannot be the reason for this.

The intersting part from error stack was "protocol is disabled or cipher suites are inappropriate". Seems cipher suite SSL_DH_anon_WITH_3DES_EDE_CBC_SHA is not available for java. It's available on Oracle as per security guide. Oracle advices not to use these cipher suites to protect sensitive data. But they are useful in situatation where only encryption of traffic is needed not authentication or if communicating parties want to remain anonymous.

MOS doc 2288489.1 listed similar issue with regard to using Diffie-Hellman on JDK 1.7. It did have a link to external doc which listed enchancements on JDK 1.8 but did not help in resolving this issue.

However, it seems the DH_anon cipher suites used in 762286.1 for encryption only test case (SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_RC4_128_MD5,SSL_DH_anon_WITH_DES_CBC_SHA) seem to be indeed disable by default on 1.8. It is mentioned here "For users of Oracle 11g, the SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_RC4_128_MD5, and SSL_DH_anon_WITH_DES_CBC_SHA cipher suites are disabled by default in Java 8. To allow these cipher suites, see the Test or Revert changes to Oracle's JDK and JRE Cryptographic Algorithms section of the Java documentation".

The test case was run using JDK1.8 and 19.11.0.0.0 driver. Using SSLServerSocketFactory is possible to iterate over available cipher suites and default cipher suites.
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
String[] defaultCiphers = ssf.getDefaultCipherSuites();
String[] availableCiphers = ssf.getSupportedCipherSuites();
This showed following list of cipher suites available by default
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384


SSL_DH_anon_WITH_3DES_EDE_CBC_SHA was missing from the list.



Document here shows how to add algorithm to disable list. So to enable then it must be taken out of the disabled list. By deafult $JAVA_HOME/jre/lib/security/java.security has the following for jdk.tls.disabledAlgorithms entry.
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves
To enable DH_anon remove "3DES_EDE_CBC, anon". So the udpate entry looks like below.
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, NULL, \
    include jdk.disabled.namedCurves
The new cipher suite list is shown below
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_128_CBC_SHA256
TLS_DH_anon_WITH_AES_128_GCM_SHA256
TLS_DH_anon_WITH_AES_256_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA256
TLS_DH_anon_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_anon_WITH_AES_128_CBC_SHA
TLS_ECDH_anon_WITH_AES_256_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384

SSL_DH_anon_WITH_3DES_EDE_CBC_SHA is available now. The other two *DH_anon_* cipher suite listed on 762286.1 seem to be missing from 19c (as it is not listed on security guide, possibly desupported in newer versions). Only SSL_DH_anon_WITH_3DES_EDE_CBC_SHA is listed on security guide as a possible cipher suite for encryption only. So getting SSL_DH_anon_WITH_3DES_EDE_CBC_SHA available is enough to run the test case mentioned on 762286.1.
java -Doracle.net.tns_admin=. JDBCSSLTester2 test2.properties
Start: Wed Jun 23 13:47:47 UTC 2021
Conncted as DATABASE USER ASANGA
Ended: Wed Jun 23 13:47:49 UTC 2021
There's a good reason why certain cipher suits are disabled by default. Enabling and using them must be carefully considerd inline with security policies being used.