I stumbled upon some obstacles while configuring a secured connection between WebSphere Application Server 6.1.0.17 and Oracle 10g Release 2 over TCPS. The requirement was to establish an encrypted connection with server (i.e. database listener) authentication. It is realized in the second scenario described in Oracle's guide for enabling SSL on JDBC thin driver. It seems all pretty straightforward and in fact it is — on the Sun's JVM the following code works like a charm (tested with ojdbc14.jar
for Oracle 10g Release 2):
import java.util.Properties; import java.sql.*; class OracleSSLTest { public static void main(String[] args) throws Exception { DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle)(PORT=2484)) (CONNECT_DATA=(SERVICE_NAME=TESTSSL)(SERVER=DEDICATED)))"; Properties props = new Properties(); props.setProperty("user", "testssl"); props.setProperty("password", "testssl"); props.setProperty("javax.net.ssl.trustStore", "client.jks"); props.setProperty("javax.net.ssl.trustStoreType", "JKS"); props.setProperty("javax.net.ssl.trustStorePassword", "password"); Connection conn = DriverManager.getConnection(url, props); System.out.println("Great success!"); } }
However, the same code launched on IBM JVM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux amd64-64 j9vmxa6423-20080315) generates the following exception:
Exception in thread "main" java.sql.SQLException: I/O Exception: The Network Adapter could not establish the connection at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:255) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:387) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:441) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801) at java.sql.DriverManager.getConnection(DriverManager.java:562) at java.sql.DriverManager.getConnection(DriverManager.java:155) at OracleSSLTest.main(Test.java:15)
I've checked that GIJ behaves similar. Running the code with a newer JDBC driver, namely ojdbc5.jar
, gives more descriptive messages (the improved verbosity of the new drivers can save you a lot of time):
Exception in thread "main" java.sql.SQLException: The Network Adapter could not establish the connection at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:412) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503) at java.sql.DriverManager.getConnection(DriverManager.java:562) at java.sql.DriverManager.getConnection(DriverManager.java:155) at OracleSSLTest.main(Test.java:15) Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:359) at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:422) at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:672) at oracle.net.ns.NSProtocol.connect(NSProtocol.java:237) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301) ... 7 more Caused by: oracle.net.ns.NetException: The ssl protocol specified is not supported. at oracle.net.nt.TcpsConfigure.configureVersion(TcpsConfigure.java:181) at oracle.net.nt.TcpsNTAdapter.setSSLSocketOptions(TcpsNTAdapter.java:146) at oracle.net.nt.TcpsNTAdapter.connect(TcpsNTAdapter.java:121) at oracle.net.nt.ConnOption.connect(ConnOption.java:123) at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:337) ... 12 more Caused by: java.lang.IllegalArgumentException: SSLv2Hello at com.ibm.jsse2.mb.a(mb.java:6) at com.ibm.jsse2.lb.<init>(lb.java:16) at com.ibm.jsse2.jc.setEnabledProtocols(jc.java:245) at oracle.net.nt.TcpsConfigure.configureVersion(TcpsConfigure.java:177) ... 16 more
This difference between Sun's and IBM's JVMs is documented. I don't want to use SSLv2
(which is considered insecure now) in any form anyway, so I added another property:
props.setProperty("oracle.net.ssl_version", "3.0");
Enforcing SSL or TSL on the listener side in listener.ora
doesn't do the trick. I've written some enhanced version of the test to simulate more accurately what I believe WAS is doing while establishing the connection:
import java.util.Properties; import java.sql.*; import javax.sql.*; import oracle.jdbc.pool.OracleConnectionPoolDataSource; class OracleSSLTest { public static void main(String[] args) throws Exception { DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver()); String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle)(PORT=2484)) (CONNECT_DATA=(SERVICE_NAME=TESTSSL)(SERVER=DEDICATED))" + "(SECURITY=(SSL_SERVER_CERT_DN=\"CN=testssl,C=PL\")))"; Properties props = new Properties(); props.setProperty("user", "testssl"); props.setProperty("password", "testssl"); props.setProperty("javax.net.ssl.trustStore", "client.jks"); props.setProperty("javax.net.ssl.trustStoreType", "JKS"); props.setProperty("javax.net.ssl.trustStorePassword", "password"); props.setProperty("oracle.net.ssl_server_dn_match", "true"); props.setProperty("oracle.net.ssl_version", "3.0"); Connection conn = DriverManager.getConnection(url, props); System.out.println("Great success!"); OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource(); ds.setURL(url); // setting username and password once again through datasource methods seems to be required as exception is thrown otherwise ds.setUser("testssl"); ds.setPassword("testssl"); ds.setConnectionProperties(props); PooledConnection pc = ds.getPooledConnection(); System.out.println("Another great success!"); } }
Since the test run without an error also with ojdbc14.jar
, I switched to the Integrated Solutions Console to create the data source with the above properties. One thing to keep in mind is that the properties to be passed to the OracleConnectionPoolDataSource
factory must be defined as a value of a newly created custom property connectionProperties
in the following form:
javax.net.ssl.trustStore=client.jks; javax.net.ssl.trustStoreType=JKS; javax.net.ssl.trustStorePassword=password; oracle.net.ssl_server_dn_match=true; oracle.net.ssl_version=3.0
Another problem one may encounter is using an anonymous cipher. Trying to limit ciphers probed during the handshake with the statement:
props.setProperty("oracle.net.ssl_cipher_suites", "(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_RC4_128_MD5, SSL_DH_anon_WITH_DES_CBC_SHA)");
Effects in the following exception:
Exception in thread "main" java.sql.SQLException: I/O Exception: IBM's Client TrustManager does not allow anonymous cipher suites: SSL_DH_anon_WITH_3DES_EDE_CBC_SHA at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:421) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503) at java.sql.DriverManager.getConnection(DriverManager.java:562) at java.sql.DriverManager.getConnection(DriverManager.java:155) at OracleSSLTest.main(Test.java:15) Caused by: javax.net.ssl.SSLHandshakeException: IBM's Client TrustManager does not allow anonymous cipher suites: SSL_DH_anon_WITH_3DES_EDE_CBC_SHA at com.ibm.jsse2.eb.serverHello(eb.java:199) at com.ibm.jsse2.eb.a(eb.java:54) at com.ibm.jsse2.db.m(db.java:208) at com.ibm.jsse2.db.a(db.java:259) at com.ibm.jsse2.jc.a(jc.java:271) at com.ibm.jsse2.jc.g(jc.java:403) at com.ibm.jsse2.jc.a(jc.java:401) at com.ibm.jsse2.j.write(j.java:10) at oracle.net.ns.Packet.send(Packet.java:385) at oracle.net.ns.ConnectPacket.send(ConnectPacket.java:173) at oracle.net.ns.NSProtocol.connect(NSProtocol.java:283) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301) ... 7 more
IBM documents a way to implement own TrustManager
and override the default with SSLContext.init()
method for your own code, but it obviously doesn't hit the spot. There is another solution in the documentation that suggests to add the line com.ibm.ssl.skipDefaultTrustManagerWhenCustomDefined=true
at the top of the ssl.client.props
file and define the custom trust manager with com.ibm.ssl.customKeyManager
thereabouts, but it doesn't work for me.
You are the man!!! I have been searching long and hard to find out how to do just this in a data source in WAS. thanks!
ReplyDeleteYou are welcome :)
ReplyDeletehello please i want to do this on websphere v7 so my question is :
ReplyDeleteis the same procedure as described on this article useful for the websphere i want to apply it on?
@Anonymous Unfortunately, I don't work with WAS anymore and I cannot tell if it changed in the next version.
ReplyDeleteok thank you
ReplyDeletethanks for sharing this article to us ,it is very nice article Thanks for sharing the details!...best regards.
ReplyDeleteLinux Training in Hyderabad
Wow, awesome blog layout! How long have you been blogging for?
ReplyDeleteyou made blogging look easy. The overall look of your
site is magnificent, let alone the content!
my web page :: >> 부산오피
(jk)
This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion.
ReplyDeleteFrom the tons of comments on your articles, I guess I am not the only one having all the enjoyment here keep up the good work
Review my webpage - ..>> 안마
(jk)
ReplyDeleteI’m not that much of a internet reader to be honest but your blogs really nice,
keep it up! I’ll go ahead and bookmark your site to come back in the future. Many thanks|
Feel free to surf to my page - 오피
(freaky)
Toto Safe Park is the preferred online gaming site for Toto site users. A variety of Toto sports and games have been reported live, and time money can be won depending on the tournament. Here's a guide to ranking the top areas that Toto users love. 토토사이트 룰렛 안전놀이터
ReplyDeletefon perde modelleri
ReplyDeleteSms Onay
Türk Telekom Mobil Ödeme Bozdurma
HTTPS://NFTNASİLALİNİR.COM
Ankara evden eve nakliyat
trafik sigortası
dedektor
kurma websitesi
aşk kitapları
elf bar
ReplyDeletebinance hesap açma
sms onay
CWWA4
betmatik
ReplyDeletekralbet
betpark
tipobet
slot siteleri
kibris bahis siteleri
poker siteleri
bonus veren siteler
mobil ödeme bahis
L5N6V
elazığ
ReplyDeletekağıthane
kastamonu
nevşehir
niğde
yalova
UQH
bilecik
ReplyDeletegebze
ısparta
şırnak
alsancak
ETXZ
salt likit
ReplyDeletesalt likit
HWNLU