Oracle密码复杂度验证默认不生效,是因为utlpwdmg.sql仅创建验证函数而未绑定到profile;必须手动执行ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function才能启用。
Oracle密码复杂度验证为什么默认不生效
执行了 @?/rdbms/admin/utlpwdmg.sql,但新建用户或改密时依然能设 '123456' 这种弱密码——根本原因是脚本只创建验证函数 verify_function(或 ora12c_strong_verify_function),并不自动绑定到 profile。oracle 不会自己把函数塞进密码策略里。
- 必须显式修改 profile(通常是
DEFAULT)的PASSWORD_VERIFY_FUNCTION参数 - 12c 及以后版本推荐用
ora12c_strong_verify_function,它比旧版verify_function多校验大小写、数字、特殊字符组合 - 如果数据库是 19c+ 且启用了统一审计(unified auditing),还要确认当前用户有
ADMINISTER KEY MANAGEMENT权限,否则调用验证函数可能报ORA-28031
怎么让 utlpwdmg.sql 的函数真正起作用
分两步:先确认函数已安装,再把它挂到 profile 上。别跳过检查环节,很多人卡在函数名拼错或 schema 没指定对。
- 查函数是否存在:
SELECT object_name FROM dba_objects WHERE object_type = 'FUNCTION' AND object_name LIKE '%VERIFY%'; - 绑定到 DEFAULT profile:
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function; - 如果要用自定义函数(比如改过源码),确保函数在
SYS下编译成功,且声明为AUTHID DEFINER - 注意:修改 profile 后,新策略只对后续的
CREATE USER或ALTER USER ... IDENTIFIED BY生效,不影响已有用户的当前密码
ORA-28003 密码验证失败的常见触发条件
不是所有报这个错都是脚本没装好,更多是参数配置和业务逻辑冲突。比如开发测试库临时关策略,上线前忘了开,结果应用批量建用户全跪了。
- 密码含用户名(
USER字符串本身)、倒序用户名、或连续重复字符(如aaaaaa)会直接拒绝 - 12c+ 函数强制要求至少 1 个大写字母、1 个小写字母、1 个数字、1 个特殊字符,且长度 ≥ 8 —— 很多老系统脚本硬编码了 6 位纯数字密码
- 如果 profile 设了
PASSWORD_REUSE_MAX和PASSWORD_REUSE_TIME,而用户试图重用近期用过的密码,也会被验证函数拦截,错误信息还是ORA-28003 - 函数内部调用
DBMS_RANDOM.STRING生成随机盐值时,若权限不足,可能静默失败导致验证逻辑异常(表现为“明明符合规则却报错”)
19c 以后用 VERIFY_FUNCTION 还安全吗
不建议。Oracle 官方在 19c 文档里明确标注 verify_function 已废弃(deprecated),它不校验 Unicode 字符、不防字典爆破、规则硬编码在 PL/SQL 里难审计。
- 优先用
ora12c_strong_verify_function,它支持通过DBA_PROFILES动态调整最小长度、字符类型数量等参数 - 若需更细粒度控制(比如禁止手机号、邮箱格式密码),得自己写函数,但必须继承
ora12c_strong_verify_function的基础校验逻辑,否则绕过核心检查 - 特别注意:自定义函数里不要用
UTL_HTTP或UTL_FILE,密码验证阶段 Oracle 限制外部包调用,否则报ORA-06512并导致整个 ALTER USER 失败
真正麻烦的不是跑通脚本,而是验证函数一旦启用,所有自动化建库、CI/CD 中的用户初始化、甚至 Oracle Data Pump 导入时的密码重置都会受约束。上线前务必在测试环境用真实建库脚本跑一遍全流程。

















