ORA-01017主因是SEC_CASE_SENSITIVE_LOGON=TRUE导致密码字节级校验失败,需同步检查SQLNET.ALLOWED_LOGON_VERSION_SERVER、密码版本、连接字符串引号/BOM及重置哈希。

Oracle 11g 起默认启用 SEC_CASE_SENSITIVE_LOGON=TRUE,旧系统若未显式加引号、未清理 BOM/空格、或仍用旧协议连接,就会因字节级比对失败直接报 ORA-01017——这不是“输错了”,是服务端拒绝了认证。
为什么大小写敏感会让旧应用突然连不上
旧系统(尤其 .NET、Java 或配置文件驱动的连接)通常不加双引号传密码,且习惯从记事本、邮件、JSON 配置里读取凭据。而 SEC_CASE_SENSITIVE_LOGON=TRUE 后,Oracle 会严格校验:
- 密码中任意一个大写字母 vs 小写,算不同值
- Windows 记事本保存的 UTF-8 文件带 BOM(EF BB BF),粘贴进连接字符串后,密码末尾多出三个不可见字节
- 换行符、尾部空格、制表符全参与哈希计算
- 用户名不加引号时自动转大写,但密码不会自动标准化,大小写必须字面一致
SQLNET.ALLOWED_LOGON_VERSION_SERVER=12a 是隐藏推手
Oracle 19c 默认把 SQLNET.ALLOWED_LOGON_VERSION_SERVER 设为 12a,强制使用 SHA-512 哈希(即 “12C” 密码版本),而该版本只支持大小写敏感认证。此时即使你设了 SEC_CASE_SENSITIVE_LOGON=FALSE,Oracle 也会跳过校验逻辑,直接返回 ORA-01017。
关键点:
- SELECT username, password_versions FROM dba_users WHERE username = 'SCOTT'; 若返回含 12C,说明用户已落入强密码闭环
- 单改数据库参数无效,必须同步修改 $ORACLE_HOME/network/admin/sqlnet.ora:
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8<br>SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
- 8 表示回退到 10g 兼容模式,支持大小写不敏感的 DES 哈希
.NET 和 JDBC 连接字符串里的引号陷阱
Oracle.ManagedDataAccess 和 ojdbc 对引号极其敏感,错一处就导致凭据截断或标准化失败:
- 用户名含小写或下划线?必须写成 User Id="my_user",否则当作 MY_USER
- 密码含 @、/、:、$?必须包裹:Password="Pass@123"
- C# 普通字符串中反斜杠要双写:Password="pass\word";更稳妥用逐字字符串:@'User Id=scott; Password="TiGeR@123";'
- 从 appsettings.json 读取?务必 .Trim(),否则 Windows 配置文件常带 BOM 或尾部空格
- 连接池开启时,首次失败的连接可能被复用,后续 Open() 仍报 ORA-01017;临时加 Pooling=false 可隔离问题
重置密码不是“再输一遍”,而是重建哈希链
即使你想保持原密码不变,也必须执行 ALTER USER scott IDENTIFIED BY "TiGeR@123":
- 旧密码哈希是按 12C 规则生成的,与新协议不兼容
- 不重置就改参数,Oracle 仍拿旧哈希去匹配新规则,必然失败
- 若用户 profile 绑了 PASSWORD_VERIFY_FUNCTION(如 ora12c_strong_verify_function),需先清空:ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION NULL;
- 执行完记得刷新共享池:ALTER SYSTEM FLUSH SHARED_POOL;,否则部分会话可能缓存旧验证路径
真正麻烦的不是参数开关,而是密码哈希版本、客户端协议、profile 策略、连接字符串解析这四层必须对齐——漏掉任何一层,ORA-01017 就会照常报,且不告诉你哪一层坏了。











