oracle 用密码复杂度

来源:互联网 发布:comic studio mac 编辑:程序博客网 时间:2024/06/05 05:02
>sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on 星期一 3月 25 22:53:24 2013

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @?/rdbms/admin/utlpwdmg.sql


转自:http://blog.itpub.net/23135684/viewspace-757083/

或者自定义脚本
-----------------------------------脚本如下--------------------------------------------
CREATE OR REPLACE FUNCTION PASSWORD_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);  
   specialarray varchar2(14);  
   chararray varchar2(52);
   i_char varchar2(10);  
   simple_password varchar2(10);  
   reverse_user varchar2(32);  
  
BEGIN   
   digitarray:= '0123456789';  
   chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';  
    specialarray:= '~!@#$%^&*()_<>'; 
  
   -- 校验密码长度至少为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;  
  
  
    -- 3. 检验特殊字符
   <<findchar>>  
   ischar:=FALSE;  
   FOR i IN 1..length(specialarray) LOOP   
      FOR j IN 1..m LOOP   
         IF substr(password,j,1) = substr(specialarray,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 special_char');  
   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;  


--------------------------------------------------------------------------------------