Oracle 11g post PSU Oct18 设置ssl连接(使用wallets)

说明

oracle 11g 从PSU 2018Oct(含)及之后的补丁不支持MD5. 要使用JDBC SSL要使用TSL1.2.

有两种方法,一种使用wallet, 一种使用JKS. 本文档使用wallets.

1. 为什么用TSL 1.2

https://blogs.oracle.com/developers/post/ssl-connection-to-oracle-db-using-jdbc-tlsv12-jks-or-oracle-wallets-122-and-lower#Wallets

提到:

JDK 7 and JDK 8 releases support TLSv1.2 protocol. The other protocols

such as TLSv1.1, TLSv1, SSLv3, and SSLv2 have security vulnerabilities

and the recommendation is to use the latest standard version TLSv1.2

and use more secure SSL cipher suites. Follow these pre-requisites

below to use TLSv1.2.

TLS 1.2是比较稳定的版本。建议使用它。

2. 使用TSL 1.2 ,需要什么环境

1) ojdbc8.jar

上文提到, 需要ojdbc8.jar, (是jdbc 12.2.0.1 的ojdbc8.jar).

注意,这里的12.2.0.1,不是数据库的版本。 而是JDBC Drivers的版本号。

更多版本参看:

https://www.oracle.com/database/technologies/appdev/jdbc-drivers-archive.html

实际从19c的$ORACLE_HOME/jdbc下得到ojdbc8.jar. 看其readme, 是12.2.0.1.0, 满足要求。:

Oracle JDBC Drivers release 12.2.0.1.0 production Readme.txt

如果从Oracle数据库12cR2的$ORACLE_HOME/jdbc下,看其readme, jdbc 版本是12.1.0.1.0 ,不满足要求。

Oracle JDBC Drivers release 12.1.0.1.0 production Readme.txt

另外几个jar获取方法,$ORACLE_HOME/jlib目录下:

bash 复制代码
cd $ORACLE_HOME/jlib
[oracle@RHEL8 jlib]$ cp oraclepki.jar /tmp
[oracle@RHEL8 jlib]$ cp osdt_cert.jar  /tmp
[oracle@RHEL8 jlib]$ cp osdt_core.jar  /tmp
cd /home/oracle/jdbc_tsl
cp /tmp/*.jar .

2) java环境。

需要JDK9 or JDK8u162或者以上

实际使用版本:1.8.0_391.

bash 复制代码
[oracle@RHEL8 trace]$ which java
/usr/local/jdk/bin/java
[oracle@RHEL8 trace]$ java -version
java version "1.8.0_391"
Java(TM) SE Runtime Environment (build 1.8.0_391-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.391-b13, mixed mode)

3. 如何确认jdbc版本和Oracle数据库的支持情况?

  • 文档: How To Configure Oracle JDBC Thin Driver To Connect To Database
    Using TLS v1.2 (Doc ID 2436911.1)
  • 文档 Starting With Oracle JDBC Drivers - Installation,
    Certification, and More! (Doc ID 401934.1)

从oracle客户端和数据库之间兼容表:

Client / Server Interoperability Support Matrix for Different Oracle Versions (Doc ID 207303.1)

可以看到:

Client

Version Server Version

23ai 21c 19c 18c 12.2.0 12.1.0 11.2.0

23ai#11 Yes Yes Yes No No No No

21c Yes Yes Yes Was Was Yes#12 No

19c Yes Yes Yes Was Was Yes#12 Yes#9

18c No Was Was Was Was Was Was#9

12.2.0 No Was Was Was Was Was Was#9

12.1.0 No Yes#12 Yes#12 Was Was Yes#12 Yes#12

11.2.0 No No Yes#9 Was#9 Was#9 Yes#12 Yes#9

数据库 11.2.0 ,客户端可以是 11.2.0, 直到 19c.

4. 其他参考文档

1)TLS Connection String For JDBC Thin Driver Without A Wallet (Doc ID 2970468.1)

把wallet的内容转化为jks

5. 步骤

先在数据库服务器上测试。

1) 生成数据库服务器的wallet

复制代码
[oracle@RHEL8 scripts]$ cat ssl_sha256_onlyserver.sh
if [ -d /home/oracle/wallets ]; then
        mv /home/oracle/wallets /home/oracle/wallets-`date +%y%m%d-%H%M%S`
fi
mkdir -p /home/oracle/wallets
cd /home/oracle/wallets #进入当前目录

orapki wallet create -wallet ./server_wallet -auto_login -pwd Welcome1_
orapki wallet add -wallet ./server_wallet -sign_alg sha256 -dn "CN=server" -keysize 1024 -self_signed -validity 365 -pwd Welcome1_
orapki wallet display -wallet ./server_wallet
orapki wallet export -wallet ./server_wallet -dn "CN=server" -cert ./server_wallet/cert.txt
# check the alg
openssl x509 -noout -text -in ./server_wallet/cert.txt

注意, 生成wallet时,java.seciruty不能加下面的

security.provider.7=oracle.security.pki.OraclePKIProvider

否则执行失败。要先注释掉再生成wallet. 然后再加上。

2) Add the required dependant jars for using Oracle Wallets

bash 复制代码
cd $ORACLE_HOME/jlib
[oracle@RHEL8 jlib]$ cp oraclepki.jar /home/oracle/jdbc_tsl
[oracle@RHEL8 jlib]$ cp osdt_cert.jar  /home/oracle/jdbc_tsl
[oracle@RHEL8 jlib]$ cp osdt_core.jar  home/oracle/jdbc_tsl

3) Enable Oracle PKI provider

bash 复制代码
$ORACLE_HOME/jdk/jre/lib/security/java.security
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
最后一行加上
security.provider.7=oracle.security.pki.OraclePKIProvider

4) 配置侦听

添加tpcs的端口

bash 复制代码
SSL_CLIENT_AUTHENTICATION = FALSE
WALLET_LOCATION =
  (SOURCE =
    (METHOD = FILE)
    (METHOD_DATA =
      (DIRECTORY = /home/oracle/wallets/server_wallet)
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = RHEL8.localdomain)(PORT = 1521))
    )
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCPS)(HOST = 192.168.56.89)(PORT = 2484))
    )
  )

ADR_BASE_LISTENER = /u01/app/oracle

修改sqlnet.ora

NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)

ADR_BASE = /u01/app/oracle

SSL_CLIENT_AUTHENTICATION = FALSE
WALLET_LOCATION =
  (SOURCE =
    (METHOD = FILE)
    (METHOD_DATA =
      (DIRECTORY = /home/oracle/wallets/server_wallet)
    )
  )

SQLNET.AUTHENTICATION_SERVICES= (BEQ,TCPS, NTS)

5) 重启侦听

bash 复制代码
lsnrctl stop
lsnrctl start

6) 修改测试java程序

下载测试程序,

https://github.com/oracle-samples/oracle-db-examples/blob/main/java/jdbc/ConnectionSamples/DataSourceSample.java

修改连接符, 用户名密码,加入security

java 复制代码
//newline是新加的行。 连接符根据实际情况修改。

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleConnection;
import java.sql.DatabaseMetaData;

//for tsl 1.2
import java.security.Security;  //newline
import oracle.security.pki.OraclePKIProvider;  //newline

public class DataSourceSample {
  // The recommended format of a connection URL is the long format with the
  // connection descriptor.
final static String DB_URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(PORT=2484)(HOST=192.168.56.89))"
    + "(CONNECT_DATA=(SERVICE_NAME=orcl))"
    + "(SECURITY=(SSL_SERVER_CERT_DN=\"CN = server\")))";

  // For ATP and ADW - use the TNS Alias name along with the TNS_ADMIN when using 18.3 JDBC driver
  // final static String DB_URL="jdbc:oracle:thin:@wallet_dbname?TNS_ADMIN=/Users/test/wallet_dbname";
  // In case of windows, use the following URL
  // final static String DB_URL="jdbc:oracle:thin:@wallet_dbname?TNS_ADMIN=C:/Users/test/wallet_dbname";
  final static String DB_USER = "system";
  final static String DB_PASSWORD = "oracle";

 /*
  * The method gets a database connection using
  * oracle.jdbc.pool.OracleDataSource. It also sets some connection
  * level properties, such as,
  * OracleConnection.CONNECTION_PROPERTY_DEFAULT_ROW_PREFETCH,
  * OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES, etc.,
  * There are many other connection related properties. Refer to
  * the OracleConnection interface to find more.
  */
  public static void main(String args[]) throws SQLException {
//for tsl1.2
    Security.addProvider(new OraclePKIProvider());//newline

7) 准备测试数据employees表

为systme用户建表employees,测试使用

sql 复制代码
sqlplus system/oracle
create table employees(first_name varchar2(10), last_name varchar2(10));
insert into employees values('a','a')
commit;

8) 测试脚本run.sh

powershell 复制代码
[oracle@RHEL8 jdbc_tsl_wallets]$ cat run.sh

javac -classpath ./ojdbc8.jar:./oraclepki.jar:./osdt_cert.jar:./osdt_core.jar:. DataSourceSample.java

java -classpath ./ojdbc8.jar:./oraclepki.jar:./osdt_cert.jar:./osdt_core.jar:. \
-Doracle.net.wallet_location="(SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=/home/oracle/wallets/server_wallet)))" \
-Doracle.net.ssl_server_dn_match=true DataSourceSample

#-Doracle.net.tns_admin=./lib

9) 测试

bash 复制代码
[oracle@RHEL8 jdbc_tsl]$ ./run.sh
Driver Name: Oracle JDBC driver
Driver Version: 19.9.0.0.0
Default Row Prefetch Value is: 20
Database Username is: SYSTEM

FIRST_NAME  LAST_NAME
---------------------
a a

6. 在客户端测试

1)测试目录jdbc_tls和wallets目录复制到客户端

把/home/oracle/jdbc_tls压缩复制到客户端并解压到相同的/home/oracle/jdb_tls目录。

复制wallets目录并解压到客户端的/home/oracle/wallet目录下.

必须要复制wallets.

2) 客户端安装jdk 1.8,

bash 复制代码
#cd /usr/local; tar zxvf jdk-8u391-linux-x64.tar.gz
#ln -s /usr/local/jdk1.8.0_391 jdk

并设置oracle的PATH

bash 复制代码
export PATH=/usr/local/jdk/bin:$ORACLE_HOME/bin:$PATH

java -version 确认版本是1.8

3)客户端测试

bash 复制代码
[oracle@hol jdbc_tsl]$ ./run.sh
Driver Name: Oracle JDBC driver
Driver Version: 19.9.0.0.0
Default Row Prefetch Value is: 20
Database Username is: SYSTEM

FIRST_NAME  LAST_NAME
---------------------
a a

7. 其他错误分析参考文档

相关推荐
JIngJaneIL1 分钟前
基于Java+ vue智慧医药系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
+VX:Fegn089517 分钟前
计算机毕业设计|基于springboot + vue图书管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
杨云龙UP1 小时前
MySQL 8.0.x InnoDB 写入链路优化:Redo Log 与 Buffer Pool 扩容与缓冲区调优实战记录-20251029
linux·运维·数据库·sql·mysql
黄俊懿2 小时前
【深入理解SpringCloud微服务】Seata(AT模式)源码解析——开启全局事务
java·数据库·spring·spring cloud·微服务·架构·架构师
我命由我123452 小时前
python-dotenv - python-dotenv 快速上手
服务器·开发语言·数据库·后端·python·学习·学习方法
繁星蓝雨2 小时前
Qt优雅的组织项目结构三(使用CMakeLists进行模块化配置)——————附带详细示例代码
开发语言·数据库·qt
Jerry.张蒙3 小时前
SAP业财一体化实现的“隐形桥梁”-价值串
大数据·数据库·人工智能·学习·区块链·aigc·运维开发
无名修道院3 小时前
DVWA 靶场搭建:Windows11(phpstudy 搭建)(步骤 + 截图 + 常见问题)
数据库·网络安全·渗透测试·靶场·php·dvwa·phpstudy
CodeAmaz5 小时前
MySQL 事务隔离级别详解
数据库·mysql·事务隔离级别
千寻技术帮5 小时前
10398_基于SSM的教学评价管理系统
数据库·mysql·毕业设计·ssm·教学评价