不行,ORA-28007报错时直接用ALTER USER IDENTIFIED BY "old_password"会失败;Oracle校验的是历史哈希记录是否在PASSWORD_REUSE_TIME和PASSWORD_REUSE_MAX约束范围内,而非明文比对。
不行,alter user user identified by "old_password" 会触发校验,哪怕密码完全一致也会失败。oracle不是比对明文,而是检查历史哈希记录是否在 password_reuse_time 和 password_reuse_max 约束范围内。只要策略启用,就拦住。
核心思路是避开明文校验逻辑,分场景选择:
IDENTIFIED BY VALUES 直接写入哈希值。先查 SELECT spare4 FROM user$ WHERE name = 'USER_NAME',拿到类似 S:ABC... 或 T:DEF... 的哈希串,再执行 ALTER USER user IDENTIFIED BY VALUES 'S:ABC...'
UNLIMITED:ALTER PROFILE default LIMIT password_reuse_time UNLIMITED 和 ALTER PROFILE default LIMIT password_reuse_max UNLIMITED。注意:二者必须同时设为 UNLIMITED,只设一个反而会让密码永远无法重置CREATE USER temp_user IDENTIFIED BY "desired_password" 创建临时用户,查其 spare4 哈希,再用该哈希更新目标用户。此法不依赖 profile 修改,但需有 SELECT ANY TABLE 权限访问 user$
很多人以为改完 profile 就万事大吉,结果 JDBC 连接仍报错。这是因为 Oracle 的密码有效期和重用策略是“惰性生效”的——只有在真正执行 ALTER USER ... IDENTIFIED BY 时才会刷新内部状态。即使新旧密码相同,也必须触发一次显式修改,否则连接层仍按旧策略校验。
哈希值格式必须匹配客户端版本。12c+ 默认用 T: 开头的新哈希,但老应用可能只认 S:。如果用 spare4 查到的是 T: 哈希,而客户端是 11g,IDENTIFIED BY VALUES 可能静默失败或登录报 ORA-01017。此时得确认 SQLNET.ALLOWED_LOGON_VERSION_SERVER 设置,并考虑降级哈希生成方式(如用 11g 实例导出再导入)。