一聚教程网:一个值得你收藏的教程网站

热门教程

为何Oracle 12c连接报ORA-28040版本不匹配_通过修改SQLNET.ALLOWED_LOGON_VERSION

时间:2026-07-03 11:08:51 编辑:袖梨 来源:一聚教程网

ORA-28040错误源于客户端与数据库加密握手协议不匹配,须在数据库服务器端$ORACLE_HOME/network/admin/sqlnet.ora中配置SQLNET.ALLOWED_LOGON_VERSION_SERVER(如设为10或12),并重启监听器(lsnrctl stop/start),否则无效;该参数仅服务端生效,且JDBC Thin模式不读此文件。

ora-28040 不是驱动或密码错了,而是客户端和数据库在“用哪套加密规则握手”这件事上彻底谈崩了——必须改服务端 sqlnet.ora,只调参数不重启监听器等于白干。

SQLNET.ALLOWED_LOGON_VERSION_SERVER 必须设对,且只在服务端生效

这个参数控制数据库接受的最低客户端协议等级,值越小兼容性越强、但安全性越低。Oracle 12c R2 起已废弃无后缀的 SQLNET.ALLOWED_LOGON_VERSION,继续写它会被 Oracle 完全忽略,日志里也查不到加载痕迹。

  • SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8:Oracle 12.2+ 已移除支持,设了也无效;19c/21c 更是直接报错或静默跳过
  • SQLNET.ALLOWED_LOGON_VERSION_SERVER = 10:兼容 Oracle 10g/11g 客户端(如 PL/SQL Developer、Toad、ojdbc6),是多数遗留系统上线的稳妥起点
  • SQLNET.ALLOWED_LOGON_VERSION_SERVER = 12:强制 TLS 1.2 + SHA-2 密码校验,满足 19c 安全基线,但会拒绝所有 11g 及更早客户端

配置必须写在数据库服务器上的 $ORACLE_HOME/network/admin/sqlnet.ora(Linux/Unix)或 %ORACLE_HOME%networkadminsqlnet.ora(Windows),不是客户端机器、也不是 Navicat 或应用服务器上。

改完必须重启监听器,lsnrctl reload 不行

这个参数是监听器启动时一次性加载的静态配置,lsnrctl reload 不会重新读取。不重启,等于没改。

  • 执行 lsnrctl stoplsnrctl start
  • 如果监听器起不来,检查 sqlnet.ora 是否有语法错误(比如多等号、引号不配对、空格在等号前后)
  • 部分 RAC 或严格环境还需执行 shutdown immediate; startup; 才能让数据库进程加载新策略
  • 验证是否生效:连一次再看 $ORACLE_HOME/network/log/listener.log,搜 Authentication protocol rejected 类提示

JDBC 连接仍报 ORA-28040?别只盯服务端参数

JDBC Thin 模式完全不读 sqlnet.ora,它依赖驱动内建协议栈和 JVM TLS 支持。即使服务端设成 = 10,以下问题照样触发 ORA-28040:

  • classpath 里混了多个 Oracle 驱动 jar(比如同时存在 ojdbc6.jarojdbc8.jar
  • 用了 ojdbc6.jar 或更老驱动:它不实现 12c 新协议,也不主动降级协商;官方要求至少用 ojdbc7.jar(JDK 7+)或 ojdbc8.jar(JDK 8+)
  • JVM 默认未启用 TLSv1.2:JDK 7/8 需加启动参数 -Dhttps.protocols=TLSv1.2;JDK 11+ 默认开启,但若显式禁用过也会失败
  • 连接 URL 中写了 ?oracle.net.authentication_services=(NONE):绕过密码验证的同时,也破坏协议协商流程

OCI 模式下 sqlnet.ora 有效,但前提是你真用了它

Navicat 默认走 JDBC Thin,不读任何 sqlnet.ora。切 OCI 模式才可能生效,但有硬性条件:

  • Navicat 的 OCI 设置路径必须指向含 oci.dll(Windows)或 libclntsh.so(Linux)的目录
  • 该目录下必须有配套的 sqlnet.ora(可从服务器复制一份过来)
  • Instant Client 版本 ≥ 12.1,否则无法协商 12c+ 协议
  • 文件编码必须是 UTF-8 without BOM,否则 Oracle 读取失败——用 vi 或 Notepad++ 显式另存为 “ANSI” 或 “UTF-8 no BOM”

最常被忽略的是:你以为改了服务端参数就万事大吉,其实客户端根本没走那条路;或者你改了,但文件编码不对、路径被 $TNS_ADMIN 覆盖、监听器压根没重启——这些细节比参数值本身更容易卡住整个排查链。

热门栏目