ORA-28040错误是因客户端与服务端TLS协议不兼容所致,需在服务端sqlnet.ora中配置SQLNET.ALLOWED_LOGON_VERSION_SERVER参数并重启监听器,而非修改客户端或数据库参数。
ORA-28040 错误到底是因为什么
这个错误不是密码错了,也不是用户锁了,而是客户端和服务器在“握手”时根本没谈拢用哪种加密协议。oracle 12c 及以后默认禁用低于 tls 1.0 的旧协议(比如 sslv3),而老客户端(如 oracle 11g 客户端、某些 jdbc 驱动、甚至旧版 sql*plus)还在尝试用 sqlnet.allowed_logon_version 低于 12 的方式连接,直接被拒。
改哪个配置?改哪里?
必须改服务端的 sqlnet.ora,不是客户端,也不是数据库参数。路径通常是 $ORACLE_HOME/network/admin/sqlnet.ora(Linux/Unix)或 %ORACLE_HOME%\network\admin\sqlnet.ora(Windows)。改完要重启监听器(lsnrctl stop && lsnrctl start),否则不生效。
-
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8:允许最老的 Oracle 8i 协议(极不推荐,仅临时救急) -
SQLNET.ALLOWED_LOGON_VERSION_SERVER=11:兼容 Oracle 11g 客户端(较常见折中选择) -
SQLNET.ALLOWED_LOGON_VERSION_SERVER=12a:强制 TLS 1.2,推荐用于新环境(但要求客户端支持)
注意:SQLNET.ALLOWED_LOGON_VERSION(无 _SERVER 后缀)是 12.1 之前的旧参数,12.1+ 已废弃,设了也不起作用——很多人踩坑在这儿。
JDBC 连接失败时特别要注意
Java 应用报 ORA-28040,往往不是服务端没配对,而是驱动版本太老或 JVM 默认 TLS 版本太低。
- 用
ojdbc8.jar或更高版本(别用 ojdbc6) - JVM 启动加参数:
-Dhttps.protocols=TLSv1.2(尤其 JDK 7/8 默认不启用 TLS 1.2) - 检查连接 URL 是否含
?oracle.net.authentication_services=(NONE)——这会绕过密码验证,但也会触发协议协商异常
如果用的是 Spring Boot,还要确认 application.properties 里没硬编码过时的 oracle.jdbc.thinLogonVersion 参数。
为什么不能只调高客户端版本
客户端升级不总是可行:遗留系统可能绑死某个 ojdbc 版本;DBA 不让动生产客户端;或者你只是个前端调存储过程的人,根本没权限装新客户端。这时候服务端适配就是唯一出路——但得清楚代价:
- 设成
11会降低安全强度(允许 SHA-1 签名、RC4 加密等) - 设成
8实际上等于关闭大部分密码强度校验,审计通不过 - Oracle 19c 默认值已是
12a,往后只会更严,拖得越久,兼容性债务越重
真正该花时间的地方,其实是查清谁在用老客户端——日志里 tnsping 或监听器日志里的 VERSION= 字段比瞎调参数有用得多。

















