Tuesday, November 18, 2025

How To Make Database Client Certificate Trust Store

While helping out a customer with Oracle Database TLS configuration, they realized that they didn't have a trust store for their database clients.  I shared that there is an easy way of creating the client trust store all necessary store formats with openssl. Here's how to accomplish for Oracle wallet, Java JKS and PKCS trust store formats.

Note in all of the following examples, you will want to use your own password. For these examples, I've used Oracle123.

Get Cert Chain

The first thing to do is capture the cert-chain into a PEM file with openssl.  

OpenSSL Export Method

The easiest way to do this is via the openssl command with:

timeout 5 openssl s_client -connect <db_host>:2484 -showcerts > ~/cert-chain.pem

Standalone Oracle Database Export Method

For a standalone Oracle database, you can use orapki to export the certificate.

Setup the environment variables with:

export ORACLE_BASE="/u01/app/oracle/19c"
export ORACLE_HOME="$ORACLE_BASE/dbhome_1"
export WALLET_ROOT="$ORACLE_BASE/wallet_root"
PATH=$ORACLE_HOME/bin:$PATH


Lookup the CN= value of the CA cert chain or if self signed, the certificate subject with:

orapki wallet display -nologo -wallet $WALLET_ROOT/rootca_wallet/tls -complete


Export the certificate using the CN= value of the previous command for <cnvalue> with:

orapki wallet export -wallet $WALLET_ROOT/rootca_wallet/tls -pwd Oracle123 -dn <cnvalue> -cert ~/cert-chain.pem

Exadata Export Method

For Oracle Exadata systems, you can lookup the current certificate CN value via orapki command with:

sudo su - grid -c "orapki wallet display -nologo -wallet /var/opt/oracle/dbaas_acfs/grid/tcps_wallets -complete"


Then, use the orapki command to export the certificate to a file using the CN= value of the certificate returned from the previous command as an input (<cnvalue>) to the the following command:

sudo su - grid -c "orapki wallet export -nologo -wallet /var/opt/oracle/dbaas_acfs/grid/tcps_wallets -dn CN=<cnvalue> -cert ~/cert-chain.crt"


Then, you can view the contents of the certificate file as the grid user with:

sudo cat ~grid/cert-chain.crt

Client Wallet

For Oracle database clients using the Oracle Call Interface (OCI) and JDBC-thick drivers, you will need an Oracle wallet containing the certificate chain.  Here's how to create the client wallet with Oracle's orapki command:

mkdir clientwallet
cd clientwallet
orapki wallet create -wallet . -pwd Oracle123 -auto_login
orapki wallet add -wallet . -pwd Oracle123 -trusted_cert -cert ~/cert-chain.pem

Display the contents of the Oracle wallet with:

orapki wallet display -wallet . -complete

Java Key Store (JKS) Trust Store

For JDBC-thin clients they will need either a JKS or PKCS12 trust store.  Here is how to create the JKS trust store from the certificate: 

keytool -importcert -storepass Oracle123 -keystore clientstore.jks -alias root-ca-chain -file ~/cert-chain.pem -noprompt

Display the contents of the JKS trust store:

keytool -list -keystore clientstore.jks  -storetype JKS  -storepass Oracle123 -v

PKCS12 Trust Store

For JDBC-thin clients they will need either a JKS or PKCS12 trust store.  Here is how to create the PKCS12 trust store from the certificate: 

keytool -importcert -storepass Oracle123 -storetype PKCS12 -keystore clientstore.p12 -alias root-ca-chain -file ~/cert-chain.pem -noprompt

Display the contents of the PKCS12 trust store:

keytool -list -storetype PKCS12 -keystore clientstore.p12 -storepass Oracle123 -v

I hope this was helpful and informative.

Blessings!

Friday, November 14, 2025

Analyzing TLS Negotiation With tshark

One of the ever strengthening domains of security posture is network cryptography.  Every few years a new protocol version, set of cipher suites or key exchanges are introduced to strengthen network cryptography.    The current network cryptography standard is TLSv1.3. Looking ahead, Quantum-safe key exchange algorithms are on the horizon with ML-KEM.  However, the maximum advertised cryptographic standards don't always represent what the client and server negotiation agree upon. For example, an older version of a client may may not support modern standards and request to connect with a weaker protocol like SSLv3 or weaker cryptographic cipher suites.  This begs the question, how can you gain visibility into the negotiated terms offered by the client and agreed upon or rejected by the server.

Wireshark and its command line equivalent tshark are packet analysis tools that we can use to watch the network traffic in real time to discern the cryptographic terms offered by the client and what was accepted by the server.

Let's look at a few examples with 
1. Oracle AI Database 26 (TCP port 2484)
2. Oracle Database 19c (TCP port 2484) 
3. Oracle Unified Directory (TCP port 1636).

tshark Command

In each of the examples, we will use the following tshark command with the exception of the port number.  For database queries, we will use port 2484. For Oracle Unified Directory, we will use port 1636.

$ sudo tshark -i any -d "tcp.port==2484,ssl" -V -a duration:10 2>&1 | egrep "^    TLSv|Handshake Protocol:|Cipher Suites \(|Cipher Suite:|^            Version: |Handshake Protocol: .* Hello|Record Layer|^                Supported Version:|^            Extension: key_share|^                Key Share extension|^                    Key Share Entry:|Extension: supported_groups|Supported Group:|Curve Type:|Named Curve:|Server Params"| uniq | sed -e "s/(0x.*)//g" -e "s/^.*Handshake Protocol: Client Hello/Client requested:/g" -e "s/.*Version:/   Protocol Version:/g" -e "s/.*Cipher Suites /   Cipher Suites Requested:/g" -e "s/.*Handshake Protocol: Server Hello/Server replied with:/g" |egrep -v "Server replied with: Done|Encrypted Handshake Message|Application Data Protocol: Application Data|Handshake Protocol: Certificate|Change Cipher Spec Protocol|http-over-tls" &


Oracle AI Database 26

Here is the command run against Oracle AI 26 database with port 2484 immediately after running the tshark command.

$ $ORACLE_HOME/bin/sqlplus system/Oracle123@pdb1_ssl

SQL*Plus: Release 23.26.0.0.0 - for Oracle Cloud and Engineered Systems on Thu Nov 13 20:49:49 2025
Version 23.26.0.0.0

Copyright (c) 1982, 2025, Oracle.  All rights reserved.

Last Successful login time: Thu Nov 13 2025 20:49:20 +00:00

Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.26.0.0.0

SQL> quit
Disconnected from Oracle AI Database 26ai Enterprise Edition Release 23.26.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.26.0.0.0


Here is the result returned by tshark for Oracle AI 26 database.  

Client requested:
Client requested:
   Protocol Version: TLS 1.2 
   Cipher Suites Requested:(10 suites)
                Cipher Suite: TLS_AES_256_GCM_SHA384 
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 
                Cipher Suite: TLS_AES_128_CCM_SHA256 
                Cipher Suite: TLS_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
            Extension: supported_groups (len=56)
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: secp521r1 
                    Supported Group: secp384r1 
                    Supported Group: secp256r1 
                    Supported Group: x25519 
                    Supported Group: sect571r1 
                    Supported Group: sect571k1 
                    Supported Group: sect409r1 
                    Supported Group: sect409k1 
                    Supported Group: sect283r1 
                    Supported Group: sect283k1 
                    Supported Group: ffdhe8192 
                    Supported Group: ffdhe6144 
                    Supported Group: ffdhe4096 
                    Supported Group: ffdhe3072 
                    Supported Group: ffdhe2048 
                    Supported Group: sect233k1 
                    Supported Group: sect233r1 
                    Supported Group: secp224r1 
                    Supported Group: secp192r1 
                    Supported Group: sect163k1 
                    Supported Group: sect163r2 
   Protocol Version: TLS 1.3 
   Protocol Version: TLS 1.2 
            Extension: key_share (len=806)
                Key Share extension
                    Key Share Entry: Group: Unknown (512), Key Exchange length: 800
Server replied with:
Server replied with:
   Protocol Version: TLS 1.2 
            Cipher Suite: TLS_AES_256_GCM_SHA384 
   Protocol Version: TLS 1.3 
            Extension: key_share (len=772)
                Key Share extension
                    Key Share Entry: Group: Unknown (512), Key Exchange length: 768
Client requested:
Client requested:
   Protocol Version: TLS 1.2 
   Cipher Suites Requested:(10 suites)
                Cipher Suite: TLS_AES_256_GCM_SHA384 
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 
                Cipher Suite: TLS_AES_128_CCM_SHA256 
                Cipher Suite: TLS_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
            Extension: supported_groups (len=56)
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: Unknown 
                    Supported Group: secp521r1 
                    Supported Group: secp384r1 
                    Supported Group: secp256r1 
                    Supported Group: x25519 
                    Supported Group: sect571r1 
                    Supported Group: sect571k1 
                    Supported Group: sect409r1 
                    Supported Group: sect409k1 
                    Supported Group: sect283r1 
                    Supported Group: sect283k1 
                    Supported Group: ffdhe8192 
                    Supported Group: ffdhe6144 
                    Supported Group: ffdhe4096 
                    Supported Group: ffdhe3072 
                    Supported Group: ffdhe2048 
                    Supported Group: sect233k1 
                    Supported Group: sect233r1 
                    Supported Group: secp224r1 
                    Supported Group: secp192r1 
                    Supported Group: sect163k1 
                    Supported Group: sect163r2 
   Protocol Version: TLS 1.3 
   Protocol Version: TLS 1.2 
            Extension: key_share (len=806)
                Key Share extension
                    Key Share Entry: Group: Unknown (512), Key Exchange length: 800
Server replied with:
Server replied with:
   Protocol Version: TLS 1.2 
            Cipher Suite: TLS_AES_256_GCM_SHA384 
   Protocol Version: TLS 1.3 
            Extension: key_share (len=772)
                Key Share extension
                    Key Share Entry: Group: Unknown (512), Key Exchange length: 768

The things to note from this output is that the client requested to connect with TLS 1.3 with the TLS_AES_256_GCM_SHA384 cipher suite using an unknown 768 bit key exchange group.  The key group is actually a hybrid TLS 1.3 connection using quantum-safe ML-KEM algorithm.  This algorithm is so new that RedHat/Oracle Linux 9 does not yet have it identified and thus marks it as Unknown.  To learn more about Oracle AI 26 database support of the new quantum-safe ML-KEM algorithm, go to the "Securing Oracle AI Database 26ai for the Quantum Era" blog.  The new ML-KEM algorithm groups are identified by IANA (https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8) as:
  • MLKEM512
  • MLKEM768
  • MLKEM1024
  • SecP256r1MLKEM768
  • X25519MLKEM768
  • SecP384r1MLKEM1024
Once RedHat/Oracle 9 and Wireshark get updated to support these groups, they will be accurately represented in the tshark output.

Oracle Database 19c

Here's the SQL*Plus command that we run for Oracle 19c database with port 2484 immediately after running the tshark command:

$ $ORACLE_HOME/bin/sqlplus system/Oracle123@pdb1_ssl

SQL*Plus: Release 19.0.0.0.0 - Production on Thu Nov 13 17:44:02 2025
Version 19.25.0.0.0

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

Last Successful login time: Thu Nov 13 2025 17:29:44 +00:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.25.0.0.0

SQL> quit;
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.25.0.0.0


Here is the result returned by tshark for Oracle 19c database:

Client requested:
Client requested:
   Protocol Version: TLS 1.2 
   Cipher Suites Requested:(25 suites)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV 
            Extension: supported_groups (len=32)
                    Supported Group: secp256r1 
                    Supported Group: secp521r1 
                    Supported Group: sect571k1 
                    Supported Group: sect571r1 
                    Supported Group: secp384r1 
                    Supported Group: sect409k1 
                    Supported Group: sect409r1 
                    Supported Group: sect283k1 
                    Supported Group: sect283r1 
                    Supported Group: secp224r1 
                    Supported Group: sect233k1 
                    Supported Group: sect233r1 
                    Supported Group: secp192r1 
                    Supported Group: sect163k1 
                    Supported Group: sect163r2
Server replied with:
Server replied with:
   Protocol Version: TLS 1.2 
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
    TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
        Handshake Protocol: Server Key Exchange
            EC Diffie-Hellman Server Params
                Curve Type: named_curve 
                Named Curve: secp256r1 
    TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
        Handshake Protocol: Client Key Exchange

The things to note from the 19c connection output is that the client requested to connect with TLS 1.2 with the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite using an Elliptic Curve Diffe-Hellman key exchange. 

Oracle Unified Directory 14c

Here's the LDAP search command that we run for OUD immediately after running the tshark command with port 1636:

$ /u01/mw_oud14c/oud1/OUD/bin/ldapsearch -h poc.example.com -Z -X -p 1636 -D 'cn=Directory Manager' -j /u01/cfg/...pw -b dc=example,dc=com -s sub uid=user1 dn
dn: uid=user1,ou=People,dc=example,dc=com

 Here is the result returned by tshark for OUD directory server:

Client requested:
Client requested:
   Protocol Version: TLS 1.2 
   Cipher Suites Requested:(36 suites)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_AES_128_GCM_SHA256 
                Cipher Suite: TLS_AES_256_GCM_SHA384 
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 
               Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA 
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA 
            Extension: supported_groups (len=22)
                    Supported Group: x25519 
                    Supported Group: secp256r1 
                    Supported Group: secp384r1 
                    Supported Group: secp521r1 
                    Supported Group: x448 
                    Supported Group: ffdhe2048 
                    Supported Group: ffdhe3072 
                    Supported Group: ffdhe4096 
                    Supported Group: ffdhe6144 
                    Supported Group: ffdhe8192 
   Protocol Version: TLS 1.3 
   Protocol Version: TLS 1.2 
            Extension: key_share (len=107)
                Key Share extension
                    Key Share Entry: Group: x25519, Key Exchange length: 32
                    Key Share Entry: Group: secp256r1, Key Exchange length: 65
Server replied with:
Server replied with:
   Protocol Version: TLS 1.2 
            Cipher Suite: TLS_AES_128_GCM_SHA256 
   Protocol Version: TLS 1.3 
            Extension: key_share (len=36)
                Key Share extension
                    Key Share Entry: Group: x25519, Key Exchange length: 32

From the above output, we see that the LDAP search connected with TLS protocol version 1.3 using TLS_AES_128_GCM_SHA256  cipher suite with Elliptic Curve Diffie Hellman key exchange (x25519).

In all of the tshark examples provided, I presumed that both wireshark/tshark and sudo are available available for use on the database or directory server host.  If that is not the case you can work with your administrator to collect the tcpdump file, copy the file to another host and then run the tshark analaysis on that file.

$ sudo timeout 10 tcpdump -s 65535 -w /var/opt/tfile -i any "tcp port 1636 or tcp port 2484"

Copy the file (/var/opt/tfile or whatever name and location you used) to the host where tshark can analyize the tcpdump file.  Here is the tshark command using the tcpdump file as the input.  It is the same command as before but with an additional parameter to read the data from an input file.

$ sudo tshark -r /var/opt/tfile -i any -d "tcp.port==2484,ssl" -V -a duration:10 2>&1 | egrep "^    TLSv|Handshake Protocol:|Cipher Suites \(|Cipher Suite:|^            Version: |Handshake Protocol: .* Hello|Record Layer|^                Supported Version:|^            Extension: key_share|^                Key Share extension|^                    Key Share Entry:|Extension: supported_groups|Supported Group:|Curve Type:|Named Curve:|Server Params"| uniq | sed -e "s/(0x.*)//g" -e "s/^.*Handshake Protocol: Client Hello/Client requested:/g" -e "s/.*Version:/   Protocol Version:/g" -e "s/.*Cipher Suites /   Cipher Suites Requested:/g" -e "s/.*Handshake Protocol: Server Hello/Server replied with:/g" |egrep -v "Server replied with: Done|Encrypted Handshake Message|Application Data Protocol: Application Data|Handshake Protocol: Certificate|Change Cipher Spec Protocol|http-over-tls" 

Although Wiresharek and tshark are great external tools for analyzing the cryptographic negotiation at the network layer, my hope and desire for all network products is that they will one day log the agreed upon terms of cryptographic negotiation.  This will greatly streamline network cryptographic analysis and help IT professionals identify clients using weak cryptography that need to be updated to use modern cryptography and mischievous clients that are intentionally using weak cryptography to find weak points of entry for penetration and lateral movement once inside an organization.

Several yeas ago, OUD implemented a feature for this very purpose. It can be implemented on access and admin log publishers by setting log-connection-details:true.  For example:

set-log-publisher-prop --publisher-name "File-Based Access Logger" --set log-connection-details:true

Once enabled, secure connections log the protocol, version and cipher suite. For example:

[14/Nov/2025:17:14:29 +0000] CONNECT CONN_DETAILS conn=2 tlsVersion=TLSv1.3 cipherSuite=TLS_AES_128_GCM_SHA256

Log analytics tools such as OCI Logging Analytics can consume the log data and identify clients using weak cryptography as seen in the following dashboard example.  The upper right widget reveals clients using weak cryptographic protocols such as SSLv3, TLSv1.0, ... etc.   The widget right below it shows use of weak cryptographic cipher suites.


Details on OUD Logging Analytics is available on my blog here.

I hope you found this information informative and helpful.

Blessings!

Wednesday, November 12, 2025

Rotate Oracle Database CA-signed TLS Certificates

Transport Layer Security (TLS) certificate rotation is an annual part of database operationalization.  The purpose of this blog post is to know when and how to rotate certificate authority (CA) signed TLS certificate(s).

When To Rotate TLS Certificates

In short, the TLS certificate should be rotated before the certificate expires.  However, you have a range of operational approaches available.

1. SCHEDULE - Use your internal systems to track when each certificate should be rotated and schedule rotation at least a week in advance of certificate expiration.

2. SCAN - Proactively periodic review of each database host's certificate.  Here is a command that you can use on a Linux host to check the validity of a database server's certificate. 

timeout 3 openssl s_client -connect <database_host>:2484 2>&1 | openssl x509 -noout -text|egrep "^Certificate:|^        Issuer:|^        Subject|^        Validity|^            Not "
Certificate:
        Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
        Validity
            Not Before: Oct 27 17:49:47 2024 GMT
            Not After : Nov  6 16:19:28 2025 GMT
        Subject: CN = hrdb.dbauthdemo.com
        Subject Public Key Info:


3. SUPPORT CLIENT REACTION - Reactively respond to rejected secure client SQL connections with error "ORA-29024: Certificate validation failure". This happens when the certificate has expired but the database server has not yet been restarted.


4. SUPPORT SERVER REACTION - Reactively respond to an error logged by the database server after restarting with an expired certificate or see errors in the listener log ($ORACLE_BASE/diag/tnslsnr/hrdb/listener/trace/listener.log):  

13-NOV-2025 00:20:39 * 28791
ORA-28791: certificate verification failure
 TNS-12560: TNS:protocol adapter error
  TNS-00540: SSL protocol adapter failure

Or, secure client connections may be rejected with error  "ORA-28864: SSL connection closed gracefully" or "ORA-28860: Fatal SSL error".  These are errors that you may see after restarting a database with an expired certificate. You can use the Linux openssl command to determine if there is a valid certificate.  If "no peer certificate available" is returned, that means that the database server didn't load the certificate because it has expired.

timeout 3 openssl s_client -connect $(hostname -f):2484 -showcerts 
CONNECTED(00000003)
140280481429312:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1544:SSL alert number 40
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 339 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---


How To Rotate TLS Certificates

When it is time to rotate in the new certificate, here is the process for a certificate that is signed by a certificate authority.

1. Backup all of the existing wallets

cd $WALLET_ROOT
zip -r wallet-backup-$(date +'%Y%m%d').zip tls [0-9A-Z]*/tls


2. Download and extract the updated certificate from the certificate authority.  In my case, the downloaded zip file contains the current signed certificate (ee406cc00e4cb32a) in crt and pem formats and the certificate chain (sf_bundle-g2) in crt format.

unzip hrdb.dbauthdemo.com.zip
Archive:  hrdb.dbauthdemo.com.zip
  inflating: sf_bundle-g2.crt
  inflating: ee406cc00e4cb32a.crt
  inflating: ee406cc00e4cb32a.pem


3. Replace the certificate and certificate chain in each of the TLS wallets.

orapki wallet replace -wallet $WALLET_ROOT/tls -pwd Oracle123 -user_cert -cert $WALLET_ROOT/a5b3357724f807a.crt

orapki wallet replace -wallet $WALLET_ROOT/31E8327905743479E0632100000A7958/tls -pwd Oracle123 -user_cert -cert $WALLET_ROOT/a5b3357724f807a.crt

... for each PDBGUID wallet


4. Restart the database

5. Confirm the certificate successfully loaded with Linux openssl command or sqlplus.

Test with Linux openssl command:

timeout 3 openssl s_client -connect <database_host>:2484 2>&1 | openssl x509 -noout -text|egrep "^Certificate:|^        Issuer:|^        Subject|^        Validity|^            Not "
Certificate:
        Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
        Validity
            Not Before: Oct 27 17:49:47 2025 GMT
            Not After : Nov  6 16:19:28 2026 GMT
        Subject: CN = hrdb.dbauthdemo.com
        Subject Public Key Info:

Test with SQL*Plus command:

sqlplus system/Oracle123@pdb1_ssl

SQL*Plus: Release 19.0.0.0.0 - Production on Thu Nov 13 00:03:32 2025
Version 19.25.0.0.0

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

Last Successful login time: Thu Nov 13 2025 00:02:55 +00:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.25.0.0.0

SQL> 


6. Remove certs and certificate chain files

rm -f sf_bundle-g2.crt ee406cc00e4cb32a.crt ee406cc00e4cb32a.pem


That's it. I hope you found this information informative and helpful.

Blessings!