Oracle 19c配置强化密码校验函数提升安全性
手动绑定密码校验函数是Oracle19c安全强化的必要步骤。确认启用需查询dba_profiles,函数须在SYS下且状态VALID。utlpwdmg sql创建函数后需显式授权,且不自动切换用户profile。自定义函数签名需严格规范,长度检查应前置,并注意字符集及空格等边界场景。
Oracle 19c 为何必须手动绑定密码校验函数
Oracle 19c 默认启用的 ora12c_verify_function 相比旧版确实在密码强度上有了明显提升,但直接使用它,部分业务特定需求可能无法覆盖。例如,禁止用户名倒序、禁用常见弱口令子串——这些场景,内置函数往往无法满足。
因此,手动绑定并验证密码校验函数是否生效,不是可选项,而是必选项。许多 DBA 以为修改完 profile 就万事大吉,结果却发现新密码依然可以设置为 oracle123,因为 PASSWORD_VERIFY_FUNCTION 仍然是 NULL。

如何确认当前密码校验函数是否已启用
不要仅凭猜测,通过 SQL 执行结果即可确认。按以下三步操作:
- 执行
SELECT limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_VERIFY_FUNCTION';——如果返回NULL或空值,说明未启用。 - 如果返回了函数名(例如
ORA12C_VERIFY_FUNCTION),再确认该函数是否存在:SELECT owner, object_name, status FROM dba_objects WHERE object_name IN ('ORA12C_VERIFY_FUNCTION', 'ORA_STIG_VERIFY_FUNCTION') AND object_type = 'FUNCTION'; - 关键点:函数必须位于
SYSschema 下,且状态为VALID。否则,绑定后修改密码时会报ORA-28003,且不提示具体原因。
运行 utlpwdmg.sql 后,为什么密码仍然可以设置得很弱
脚本执行成功 ≠ 策略自动生效。以下三个常见断点容易被忽略:
@?/rdbms/admin/utlpwdmg.sql仅创建函数并修改DEFAULTprofile 的PASSWORD_VERIFY_FUNCTION参数,但不会自动将已有用户从DEFAULT切换过去。请检查:SELECT username, profile FROM dba_users WHERE username NOT IN ('SYS','SYSTEM');- 函数创建后必须显式授权:
GRANT EXECUTE ON ORA12C_VERIFY_FUNCTION TO PUBLIC;——否则非 SYS 用户调用时会静默失败。 - 19c 中
ORA12C_VERIFY_FUNCTION默认要求至少 8 位、包含大小写字母+数字+特殊字符。但如果数据库字符集是AL32UTF8,某些 Unicode 特殊字符(如中文标点)会被忽略校验,实际仅按 ASCII 范围判断。
自定义 verify_function 函数时最容易踩的三个坑
想要添加“禁止密码包含用户名拼音”或“禁用近三个月用过的密码哈希”?手写函数时,以下三点错一处,ALTER USER ... IDENTIFIED BY 就会直接报 ORA-28003,且不给出提示。
- 签名必须严格为:
FUNCTION my_verify (username IN VARCHAR2, password IN VARCHAR2, old_password IN VARCHAR2) RETURN BOOLEAN——多一个参数、少一个IN、返回NUMBER,都会导致编译通过但运行时失效。 - 函数体内不能出现
INSERT/UPDATE/DBMS_OUTPUT.PUT_LINE。调试时可以用CREATE OR REPLACE PROCEDURE debug_log(p_msg VARCHAR2) AS BEGIN NULL; END;占位,避免误触副作用。 - 长度检查必须放在最前面:
IF LENGTH(password) < 8 THEN RETURN FALSE; END IF;——否则后续REGEXP_LIKE在空密码或超短密码下可能抛出异常,中断校验流程。
生产环境启用前必须验证的边界场景
不要只测试 Abc123!@# 这种理想密码。真实用户会输入各种你写函数时未曾考虑到的诡异组合,而 Oracle 的校验函数对这些输入的处理非常“直白”。
- 密码含前导/尾随空格:
' Abc123!@# '——LENGTH返回 13,但 Oracle 实际存储时会 trim,导致校验通过后真实密码变短。 - 用户名全小写但密码用大写开头:
username='scott',password='SCOTT123'——内置函数默认不校验大小写敏感匹配,需在自定义函数里加INSTR(UPPER(username), UPPER(password)) > 0。 - 使用
ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_MAX 5后,用户修改密码时若旧密码哈希未存储够 5 条(例如之前未开启过该策略),首次修改会绕过重用检查。
真正困难的并非编写函数,而是验证它在所有用户、所有客户端(SQL*Plus、JDBC、OCI)以及所有字符集下都能稳定触发。建议在测试库中使用脚本批量测试 100 多种弱密码样本,这比仅阅读文档要可靠得多。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Redis 6.0 ACL权限控制:最小化命令授权提升安全性
Redis6 0及以上版本启用ACL时,需确认版本并修改default用户默认全开权限。按业务边界创建用户,严格绑定keypattern(如~order:*),避免漏写通配符。命令权限按输入顺序生效,推荐细粒度列举而非类别。客户端连接必须显式传递用户名,否则回退至default用户导致权限失效。
导出数据库时包含创建数据库语句的选项设置
使用mysqldump导出时,默认不包含建库语句,需添加--databases参数才能生成CREATEDATABASE和USE语句。同时,导出账号必须拥有SHOWDATABASES权限,否则会报错。注意--no-create-db参数会覆盖建库语句,导致不生成建库指令,导入前需检查目标库是否存在,并确保字符集兼容。
SQL嵌套查询使用Union与Intersect集合运算符过滤
嵌套查询中不可直接在WHERE或IN中使用UNION或INTERSECT。正确做法是将集合运算符包裹在括号内作为派生表置于FROM子句中,并显式赋予别名。对于不支持INTERSECT的数据库,可用EXISTS嵌套替代。需注意列类型对齐、别名不可省略等细节。
如何在SQL中使用BIT_COUNT函数统计二进制位数量教程
BIT_COUNT函数统计无符号整数二进制中1的个数,输入必须为非负整数,字符串或负数会导致错误。使用前应确保字段为UNSIGNED类型或通过CAST转换。该函数不走索引,频繁查询建议缓存结果。MySQL特有,其他数据库需另写逻辑。对NULL返回NULL,需用IFNULL处理。
SQL中利用JOIN查找A表不存在B表的数据
在SQL中查找A表存在而B表不存在的记录,最可靠的写法是使用LEFTJOIN并结合WHEREB idISNULL。需注意ON只用于连接逻辑,过滤条件应放在WHERE子句中;B表关联字段需要建立索引,并且要避免NULL值的陷阱。不建议使用NOTIN或EXCEPT,因为它们容易出错且性能较差。
- 热门数据榜
相关攻略
2026-07-13 07:07
2026-07-13 07:07
2026-07-13 07:07
2026-07-13 07:07
2026-07-13 07:06
2026-07-13 07:06
2026-07-13 07:06
2026-07-13 07:06
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

