ORA-01017认证失败根源在密码哈希版本与客户端协议不匹配,须查password_versions、sqlnet.ora中SQLNET.ALLOWED_LOGON_VERSION_SERVER配置及profile验证函数,降级协议后执行ALTER USER重建多版本哈希并刷新共享池。

不能靠改 sec_case_sensitive_logon 来“兼容旧密码”,必须同步调整认证协议版本、重建密码哈希、清理验证函数,否则所有客户端连接都会卡在 ORA-01017 或 ORA-28040。
查清当前用户密码版本和协议限制
先确认问题根源,不是猜。一个用户登录失败,可能是因为它的密码只存了 12C 版本哈希,而客户端只支持 11G 协议;也可能是因为服务器端强制要求 12C 认证但没生成对应哈希。
- 运行
SELECT username, password_versions FROM dba_users WHERE username = 'SCOTT';—— 若返回只有12C,说明没有11G或10G哈希 - 查数据库级协议控制:
SELECT name, value FROM v$parameter WHERE name IN ('sec_case_sensitive_logon', 'sqlnet.allowed_logon_version_server'); - 检查
$ORACLE_HOME/network/admin/sqlnet.ora文件里是否显式设置了SQLNET.ALLOWED_LOGON_VERSION_SERVER,该值优先于参数(如果存在)
降级认证协议并触发多版本哈希生成
只改参数不改配置文件,等于白设。19c 默认把 SQLNET.ALLOWED_LOGON_VERSION_SERVER 设为 12 或 12a,这会阻止旧客户端协商成功,也禁止生成 11G 哈希。
- 编辑
$ORACLE_HOME/network/admin/sqlnet.ora,加入或修改两行:SQLNET.ALLOWED_LOGON_VERSION_SERVER=11和SQLNET.ALLOWED_LOGON_VERSION_CLIENT=11 - 不需要重启监听,新连接立即生效;但已有连接仍用旧协商结果
- 让密码重新“过一遍”才能生成新哈希:对每个关键用户执行
ALTER USER scott IDENTIFIED BY VALUES 'S:...';(用原SPARE4值)或ALTER USER scott IDENTIFIED BY scott ACCOUNT UNLOCK; - 执行后立刻查
password_versions,应出现11G 12C—— 表示双版本哈希已就位
清空 PROFILE 中的密码验证函数
即使协议降级、哈希重建,只要用户 profile 还绑着 ORA12C_STRONG_VERIFY_FUNCTION,下次重置密码就会被强制校验大小写/长度/特殊字符,导致运维无法设回原来那个简单密码。
- 查绑定关系:
SELECT username, profile FROM dba_users WHERE username = 'SCOTT';,再查该 profile:SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_VERIFY_FUNCTION'; - 清空验证函数:
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION NULL;(如果是自定义 profile,替换DEFAULT) - 注意:该操作不影响已存在的密码,只影响后续
ALTER USER ... IDENTIFIED BY的行为 - 如果 profile 是只读的(如
ORA_STIG_PROFILE),需先CREATE PROFILE复制一份再修改
避免用 IDENTIFIED BY 直接触发复杂度校验
很多 DBA 在用户过期后直接敲 ALTER USER scott IDENTIFIED BY abc123;,结果报 ORA-28003 —— 不是命令错,是 PASSWORD_VERIFY_FUNCTION 拦住了。这时别硬刚规则,换路径。
- 优先用
IDENTIFIED BY VALUES:从sys.user$.SPARE4取值,ALTER USER scott IDENTIFIED BY VALUES 'S:...';—— 完全绕过所有校验 - 若无原哈希值,且必须设新密码,先临时禁用验证函数(上一步),设完再恢复(如果合规要求允许)
- 设完密码后,务必执行
ALTER SYSTEM FLUSH SHARED_POOL;,否则部分客户端可能因缓存旧哈希而继续报ORA-01017 - 不要依赖
utlpwdmg.sql创建的默认函数,它在 19c 下对 11g 客户端极不友好;真要保留复杂度,得自己写轻量函数
最易被忽略的是:SQLNET 配置文件里的 ALLOWED_LOGON_VERSION_SERVER 和数据库参数 sqlnet.allowed_logon_version_server 不是一回事,前者是静态配置,后者是动态参数,且前者优先级更高;改错地方,等于没改。


















