oracle最简便的密码校验函数,profile的使用

本文介绍如何在Oracle数据库中利用内置脚本utlpwdmg.sql创建和定制密码策略,包括密码复杂度、账户过期和密码过期策略。通过修改此脚本,你可以为不同类型的用户提供特定的密码策略,简化数据库管理。

生产中我们不同用户通常有不同的策略,例如应用连接用户我们希望密码永不过期,维护用户为了安全要几个月修订一次,大家知道oracle非常强大,这些功能都能在oracle中实现。但是过程往往觉得很麻烦,如密码策略如何自建,profile格式等问题。其实oracle 自带的脚本中已经给我写好了密码校验策略。

本案就教大家最简洁的如何限定oracle用户密码复杂度,账户过期策略,密码过期策略以及针对不同用户设置不同的策略。

脚本位于$ORACLE_HOME/rdbms/admin/utlpwdmg.sql 中,我们只要修改部分语句就可以建立自己的密码策略。

数据库版本11.2.0.3

脚本如下,基本包含密码的各种策略,可以根据自己的要去自己修改。

CREATE OR REPLACE FUNCTION verify_function
(username varchar2,
  password varchar2,
  old_password varchar2)
  RETURN boolean IS 
   n boolean;
   m integer;
   differ integer;
   isdigit boolean;
   ischar  boolean;
   ispunct boolean;
   db_name varchar2(40);
   digitarray varchar2(20);
   punctarray varchar2(25);
   chararray varchar2(52);
   i_char varchar2(10);
   simple_password varchar2(10);
   reverse_user varchar2(32);

BEGIN 
   digitarray:= '0123456789';
   chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

   -- 校验密码长度至少为8位
   IF length(password) < 8 THEN
      raise_application_error(-20001, 'Password length less than 8');
   END IF;


   -- 校验密码是否和用户名相同
   IF NLS_LOWER(password) = NLS_LOWER(username) THEN
     raise_application_error(-20002, 'Password same as or similar to user');
   END IF;
   FOR i IN 1..100 LOOP
      i_char := to_char(i);
      if NLS_LOWER(username)|| i_char = NLS_LOWER(password) THEN
        raise_application_error(-20005, 'Password same as or similar to user name ');
      END IF;
    END LOOP;

   -- 校验密码是不是用户名的反序
   
   FOR i in REVERSE 1..length(username) LOOP
     reverse_user := reverse_user || substr(username, i, 1);
   END LOOP;
   IF NLS_LOWER(password) = NLS_LOWER(reverse_user) THEN
     raise_application_error(-20003, 'Password same as username reversed');
   END IF;

   -- 校验密码是否是服务名
   select name into db_name from sys.v$database;
   if NLS_LOWER(db_name) = NLS_LOWER(password) THEN
      raise_application_error(-20004, 'Password same as or similar to server name');
   END IF;
   FOR i IN 1..100 LOOP
      i_char := to_char(i);
      if NLS_LOWER(db_name)|| i_char = NLS_LOWER(password) THEN
        raise_application_error(-20005, 'Password same as or similar to server name ');
      END IF;
    END LOOP;

   -- 检查用户密码是否过于简单,
   -- 检查密码是否有列表中的关键字
   -- 是否存在弱口令
   IF NLS_LOWER(password) IN ('welcome1', 'database1', 'account1', 'user1234', 'password1', 'oracle123', 'computer1', 'abcdefg1', 'change_on_install') THEN
      raise_application_error(-20006, 'Password too simple');
   END IF;

   -- 检查密码是否为oracle
    simple_password := 'oracle';
    FOR i IN 1..100 LOOP
      i_char := to_char(i);
      if simple_password || i_char = NLS_LOWER(password) THEN
        raise_application_error(-20007, 'Password too simple ');
      END IF;
    END LOOP;

   -- 检验密码至少包含至少一个字母,一个数字 
   -- 1. 校验数字
   isdigit:=FALSE;
   m := length(password);
   FOR i IN 1..10 LOOP 
      FOR j IN 1..m LOOP 
         IF substr(password,j,1) = substr(digitarray,i,1) THEN
            isdigit:=TRUE;
             GOTO findchar;
         END IF;
      END LOOP;
   END LOOP;

   IF isdigit = FALSE THEN
      raise_application_error(-20008, 'Password must contain at least one digit, one character');
   END IF;
   -- 2. 检验字符
   <<findchar>>
   ischar:=FALSE;
   FOR i IN 1..length(chararray) LOOP 
      FOR j IN 1..m LOOP 
         IF substr(password,j,1) = substr(chararray,i,1) THEN
            ischar:=TRUE;
             GOTO endsearch;
         END IF;
      END LOOP;
   END LOOP;
   IF ischar = FALSE THEN
      raise_application_error(-20009, 'Password must contain at least one \
              digit, and one character');
   END IF;


   <<endsearch>>
   --  检验密码和上一个密码至少有三个不同字符
   --
   IF old_password IS NOT NULL THEN
     differ := length(old_password) - length(password);

     differ := abs(differ);
     IF differ < 3 THEN
       IF length(password) < length(old_password) THEN
         m := length(password);
       ELSE
         m := length(old_password);
       END IF;

       FOR i IN 1..m LOOP
         IF substr(password,i,1) != substr(old_password,i,1) THEN
           differ := differ + 1;
         END IF;
       END LOOP;

       IF differ < 3 THEN
         raise_application_error(-20011, 'Password should differ from the \
            old password by at least 3 characters');
       END IF;
     END IF;
   END IF;
   -- Everything is fine; return TRUE ;   
   RETURN(TRUE);
END;
/

原有的脚本会将默认的profile进行修改,修改后将对所有用户生效,脚本如下

ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 180
PASSWORD_GRACE_TIME 7
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION verify_function_11G;
我们不希望对所有用户生效,进行适当修改,创建自己的profile:

CREATE PROFILE safe_control LIMIT
PASSWORD_LIFE_TIME 120
PASSWORD_GRACE_TIME 7
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION verify_function;

将脚本保存为safe_11g.sql 在服务器下执行脚本

SQL> @/home/oracle/files/safe_11g.sql

Function created.


Profile created.


现在测试下我们的profile是否生效
SQL> create user u01 identified by u01 profile SAFE_CONTROL;
create user u01 identified by u01 profile SAFE_CONTROL
*
ERROR at line 1:
ORA-28003: password verification for the specified password failed
ORA-20001: Password length less than 8


SQL> 

可以看到加上profile以后新建用户无法成功,当然我们也可以先建立用户然后,让用户使用profile。
SQL> create user u01 identified by u01;

User created.

SQL> alter user u01 profile safe_control;

User altered.

在用户过期后将修改密码将会根据我们profile要求的来进行修改

这里我们的profile里各个参数可以参见下表

参数名称

说明

默认值

建议值

PASSWORD_LIFE_TIME

账户修改时间

180天

120天

PASSWORD_LOCK_TIME

账户锁定时间

1天

30分钟

PASSWORD_REUSE_MAX

最大可用次数

Unlimited

Unlimited

PASSWORD_REUSE_TIME

多久后可以重用密码

Unlimited

Unlimited

PASSWORD_GRACE_TIME

延期天数

7

7

FAILED_LOGIN_ATTEMPTS

登录失败次数

10

10

PASSWORD_VERIFY_FUNCTION

密码校验方法

Null

verify_function


根据以上的参数,我们基本可以修改部分参数快速建立自己的密码函数,建立自己的profile,让不同用户使用不同的profile。让一切变得超简单。








<think>我们正在处理关于Oracle数据库密码修改的问题。根据引用内容,我们需要提供修改Oracle数据库密码的方法,特别是针对特权用户(如SYS、SYSTEM)和普通用户,以及处理密码过期问题的方法。 回顾引用内容: 引用[1]提到特权用户(INTERNAL/SYSDBA/SYSOPER)登录Oracle数据库的两种身份验证方式,并涉及密码文件的使用和维护。 引用[2]展示了使用orapwd工具修改密码文件(特权用户密码)的方法。 引用[3]则说明了如何修改普通用户的密码以及处理账户锁定和密码过期问题。 因此,我们可以将修改Oracle数据库密码分为两个层面: 1. 修改特权用户(如SYS)的密码(通过密码文件修改)。 2. 修改普通用户的密码(通过SQL语句)。 另外,引用[3]还提到了密码过期问题,所以我们需要包括如何修改密码策略(例如设置为永不过期)。 步骤: 1. 修改特权用户(如SYS)密码: - 使用`orapwd`工具覆盖原有的密码文件。注意:该操作会重置密码文件,因此需要确保在数据库运行期间执行,并且所有使用密码文件验证的特权用户密码都会被更新。 2. 修改普通用户密码: - 使用SQL语句:`ALTER USER 用户名 IDENTIFIED BY 新密码;` - 如果账户被锁定,还需要解锁:`ALTER USER 用户名 ACCOUNT UNLOCK;` 3. 修改密码有效期策略(防止密码过期): - 查看用户的密码过期时间:`SELECT username, expiry_date FROM dba_users;` - 修改密码为永不过期:`ALTER USER 用户名 PROFILE 指定配置文件;` (通常将配置文件改为DEFAULT,但需要确认DEFAULT配置文件是否已经设置为永不过期。或者直接修改配置文件:`ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;`) 注意:修改配置文件会影响所有使用该配置文件的用户。 根据引用[3],我们还可以在修改密码的同时解锁账户。 因此,回答结构如下: ### Oracle数据库密码修改方法 在Oracle数据库中,密码修改分为**特权用户密码修改**(如SYS、SYSDBA等)和**普通用户密码修改**两种情况。同时,还需注意密码过期策略的影响。以下是具体方法: #### 1. 修改特权用户(如SYS)密码 特权用户的密码存储在密码文件中(通常位于`$ORACLE_HOME/database`目录下,文件名为`PWD<实例名>.ora`)。修改方法: - 使用`orapwd`命令行工具覆盖原密码文件: ```bash orapwd file=<密码文件路径> password=<新密码> entries=<大允许的特权用户数> ``` 示例(Windows环境): ```bash orapwd file=D:\oracle\product\10.2.0\db_1\database\pwdorcl.ora password=newpass entries=10 ``` 说明:执行此命令需要关闭数据库实例吗?实际上,可以在数据库运行时执行,但建议在执行前备份原文件。执行后,新的密码在下次登录时生效[^2]。 #### 2. 修改普通用户密码 使用SQL*Plus或其他数据库客户端连接到数据库,执行: ```sql ALTER USER <用户名> IDENTIFIED BY <新密码>; ``` 若用户因密码过期或多次登录失败被锁定,还需解锁: ```sql ALTER USER <用户名> ACCOUNT UNLOCK; ``` 示例(将用户`scott`的密码改为`tiger`并解锁): ```sql ALTER USER scott IDENTIFIED BY tiger; ALTER USER scott ACCOUNT UNLOCK; ``` #### 3. 处理密码过期问题 若需将用户密码设置为永不过期,可通过修改用户配置文件实现: ```sql -- 修改默认配置文件,设置密码永不过期(影响所有使用默认配置文件的用户) ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; ``` 或者仅修改特定用户的配置文件(需先创建自定义配置文件并分配给用户): ```sql -- 创建自定义配置文件 CREATE PROFILE no_expiry LIMIT PASSWORD_LIFE_TIME UNLIMITED; -- 将配置文件分配给用户 ALTER USER <用户名> PROFILE no_expiry; ``` 完成上述操作后,建议重新修改用户密码使新策略生效[^3]。 ### 注意事项 - **权限要求**:修改其他用户密码需要`ALTER USER`系统权限(通常由DBA执行);修改特权用户密码需有操作系统权限(能访问Oracle安装目录)。 - **密码复杂度**:Oracle默认启用密码复杂度验证,设置密码需满足长度、大小写等要求(可通过`utlpwdmg.sql`脚本调整)。 - **生效时间**:密码修改立即生效,用户下次登录需使用密码。 §§相关问题§§ 1. 如何修改Oracle数据库的默认密码策略? 2. Oracle数据库密码文件丢失怎么办? 3. 如何批量修改Oracle数据库用户的密码? </think>### Oracle数据库密码修改方法 在Oracle数据库中,密码修改分为**特权用户密码修改**(如SYS、SYSDBA等)和**普通用户密码修改**两种情况。以下是具体操作流程: --- #### 一、特权用户密码修改(密码文件方式) 特权用户(如SYS)的密码存储在密码文件(Password File)中,需使用命令行工具修改: 1. **定位密码文件** 文件路径通常为: `$ORACLE_HOME/database/PWD<ORACLE_SID>.ora` (例如 Linux:`/u01/app/oracle/product/19c/dbhome_1/database/PWDorcl.ora`) 2. **使用`orapwd`工具覆盖密码文件** ```bash orapwd file=<密码文件路径> password=<新密码> entries=<大特权用户数> ``` **示例**(Windows环境): ```bash orapwd file=D:\oracle\product\19c\dbhome_1\database\PWDorcl.ora password=NewPass123 entries=5 ``` **注意**: - 此操作会覆盖原文件,需确保数据库实例处于运行状态[^2] - `entries`参数指定允许的特权用户数量(默认5) --- #### 二、普通用户密码修改(SQL命令方式) 通过SQL*Plus或SQLcl执行ALTER USER命令: ```sql ALTER USER <用户名> IDENTIFIED BY <新密码>; ``` **常用场景**: 1. **基础密码修改** ```sql ALTER USER scott IDENTIFIED BY tiger_2024; ``` 2. **密码过期处理**(修改为永不过期) ```sql -- 修改密码策略配置文件 ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; -- 重置用户密码并解除过期状态 ALTER USER hr IDENTIFIED BY newpass ACCOUNT UNLOCK; ``` 执行后验证: ```sql SELECT username, expiry_date FROM dba_users WHERE username='HR'; -- 应返回NULL[^3] ``` 3. **批量修改密码**(结合PL/SQL) ```sql BEGIN FOR user_rec IN (SELECT username FROM dba_users WHERE account_status='OPEN') LOOP EXECUTE IMMEDIATE 'ALTER USER ' || user_rec.username || ' IDENTIFIED BY 'NewPass$2024''; END LOOP; END; ``` --- #### 三、密码策略管理 1. **查看当前策略** ```sql SELECT * FROM dba_profiles WHERE profile='DEFAULT' AND resource_name LIKE 'PASSWORD%'; ``` 2. **关键参数调整** | 参数 | 说明 | 修改命令示例 | |------|------|--------------| | `PASSWORD_LIFE_TIME` | 密码有效期 | `ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;` | | `FAILED_LOGIN_ATTEMPTS` | 大登录失败次数 | `ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS 10;` | | `PASSWORD_REUSE_TIME` | 密码重用间隔 | `ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_TIME 365;` | --- ### 注意事项 1. **权限要求**: - 特权用户密码修改需操作系统文件访问权限 - 普通用户密码修改需`ALTER USER`系统权限 2. **密码复杂度**: - Oracle默认启用密码校验函数(如`VERIFY_FUNCTION`) - 密码需包含数字+字母+特殊字符(例:`Pass_123!`) 3. **生效时间**: - 密码文件修改立即生效 - SQL修改需提交事务(`COMMIT;`) > **故障处理**:若因密码文件损坏导致无法登录,可通过重建密码文件恢复: > ```bash > orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password=<sys_password> force=y > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值