ORA-28040错误源于客户端与服务器加密握手协议不匹配,须在服务端sqlnet.ora中成对配置SQLNET.ALLOWED_LOGON_VERSION_SERVER和_CLIENT(如均设为12),并重启监听器;JDBC连接还需确保ojdbc8+驱动及JVM启用TLSv1.2。
ora-28040 不是驱动或密码错了,而是客户端和服务器根本没谈拢用哪套加密握手规则——必须同时控制服务端协议下限和客户端协议上限,只调一个参数等于白干。
SQLNET.ALLOWED_LOGON_VERSION_SERVER 和 _CLIENT 必须成对设
Oracle 12c 起废弃了旧参数 SQLNET.ALLOWED_LOGON_VERSION,只认带后缀的两个:
SQLNET.ALLOWED_LOGON_VERSION_SERVER 控制数据库接受的最低客户端协议等级;
SQLNET.ALLOWED_LOGON_VERSION_CLIENT 控制客户端接受的最低服务器协议等级。
只改其中一个,另一端仍按默认策略拒绝连接,错误照报。
- 推荐值统一设为
12:兼容 Navicat(OCI 模式 + Instant Client 12.1+)、ojdbc7/8、SQL*Plus 12.2+,且满足 Oracle 19c 安全基线 - 设成
8或10虽能连上,但会绕过 SHA-2 密码哈希校验,DBA 通常不允许上线 - 写错参数名(比如漏掉
_SERVER后缀)会导致 Oracle 完全忽略该行,日志里查不到任何加载痕迹
sqlnet.ora 文件必须改在数据库服务器端,不是 Navicat 或应用机器上
这个文件只被 Oracle 监听器和数据库进程读取,Navicat 的 JDBC Thin 模式根本不看它;只有 OCI 模式才会加载本地 sqlnet.ora,但前提是 Navicat 明确指向了含 oci.dll 或 libclntsh.so 的目录,并且该目录下有配套的 sqlnet.ora。
- 正确路径:
$ORACLE_HOME/network/admin/sqlnet.ora(Linux/Unix)或%ORACLE_HOME%\network\admin\sqlnet.ora(Windows) - 文件编码必须是 UTF-8 without BOM,否则 Oracle 读取失败——用
vi或 Notepad++ 显式另存为 ANSI / UTF-8 no BOM - 改完必须执行
lsnrctl stop && lsnrctl start,部分环境还需shutdown immediate; startup;才能生效
JDBC 连接报 ORA-28040,大概率是驱动或 JVM 层面的问题
即使服务端参数设对了,Java 应用仍可能失败,因为 JDBC Thin 不走 sqlnet.ora,它完全依赖驱动内建协议栈和 JVM TLS 支持。
- 必须用
ojdbc8.jar(支持 Oracle 12c–21c),别用ojdbc6或更老版本 - JDK 8u161 之前默认不启用 TLS 1.2,需加启动参数:
-Dhttps.protocols=TLSv1.2 - 连接 URL 中避免出现
?oracle.net.authentication_services=(NONE),这会干扰协议协商 - Spring Boot 项目要检查是否硬编码了过时的
oracle.jdbc.thinLogonVersion属性
最容易被忽略的是:监听日志里 Authentication protocol rejected 这类提示比报错本身更早出现,它才是真正定位协议协商失败的第一手证据;而用户表的 PASSWORD_VERSIONS 字段(如显示 10G 11G)只是结果,不是原因。


















