oracle用户密码由内核自动哈希存储于sys.user$,非应用层md5;业务表密码不得手动加密,须用tde或合规算法;等保要求强制密码策略、生命周期及失败锁定。
oracle 用户密码加密存储不是靠应用层调 md5 或手写函数来“模拟”,而是由数据库内核自动完成的——你创建用户时输的明文密码,oracle 会用不可逆哈希(如 sha-1、sha-256)处理后存进 sys.user$,根本不需要你手动加密。
DBA 创建用户时密码已自动哈希
Oracle 不允许直接往 user$ 表里插哈希值;所有合法用户创建必须走 CREATE USER 语句。此时 Oracle 内部会:
- 根据当前兼容性参数(
compatible)选择哈希算法:12c+ 默认用 SHA-256,旧版本 fallback 到 SHA-1 或更早的 DES - 加盐(salt):每个用户密码哈希都带唯一随机 salt,防止彩虹表攻击
- 结果存在
password和spare4字段中,spare4存的是带 salt 的完整哈希值(Base64 编码)
你执行 CREATE USER alice IDENTIFIED BY "Passw0rd123"; 后,SELECT name, password, spare4 FROM sys.user$ WHERE name = 'ALICE'; 看到的 spare4 就是实际存储的哈希串——别试图自己复现它,Oracle 没公开 salt 生成和拼接逻辑。
不要在业务表里重复实现“密码字段 MD5”
很多项目把用户密码存在业务表(比如 USERS.U_PASSWORD)里,再用 DBMS_OBFUSCATION_TOOLKIT.MD5 或自定义 MD5() 函数去更新,这是典型误区:
-
DBMS_OBFUSCATION_TOOLKIT在 12c 后已废弃,19c+ 完全移除,调用会报PLS-00201: identifier 'DBMS_OBFUSCATION_TOOLKIT' must be declared - 纯 MD5 无 salt、无迭代,等保三级明确不接受(要求 PBKDF2、bcrypt 或 SHA-2 加 salt ≥ 1000 次迭代)
- 业务表密码字段应统一走 Oracle TDE 或应用层加密,而非自己拼 SQL 跑
UPDATE ... SET u_password = (SELECT md5(...) FROM dual)
真要迁移老系统明文密码,优先用 DBMS_CRYPTO.HASH + 自定义 salt + 多轮迭代封装函数,而不是复刻网上搜到的 MD5 封装。
等保合规真正该配的三项配置
等保对 Oracle 密码安全的要求,核心落在数据库自身策略,不是写几个函数就能过审:
- 强制密码复杂度:
ALTER PROFILE default LIMIT PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function;(启用 Oracle 自带强校验) - 密码生命周期:
ALTER PROFILE default LIMIT PASSWORD_LIFE_TIME 90 PASSWORD_GRACE_TIME 7; - 失败登录锁定:
ALTER PROFILE default LIMIT FAILED_LOGIN_ATTEMPTS 6 PASSWORD_LOCK_TIME 1/24;(锁 1 小时)
这些生效后,dba_profiles 可查,且影响所有新创建用户——比你在业务代码里反复调 DBMS_CRYPTO.ENCRYPT 实在得多。
最容易被忽略的是:Oracle 自身用户密码哈希机制和业务表密码字段是两套体系。前者由内核管,后者得你自己担责。等保检查时,如果业务表还存着 MD5(plain) 这种裸哈希,哪怕 DBA 用户密码再合规,这一项也直接不合格。











