首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 密碼驗證函數實作:複雜度、歷史比對、字典檢核

     編輯:Oracle 資料庫基礎

函數規格

函數簽名:verify_function(username, password, old_password) RETURN BOOLEAN
掛載方式:ALTER PROFILE default LIMIT PASSWORD_VERIFY_FUNCTION verify_function;

完整驗證邏輯

  1. 不可與使用者名相同(不分大小寫)。
  2. 最小長度 8 碼。
  3. 字典弱密碼檢核:welcome, database, account, user, password, oracle, computer, abcd。
  4. 至少包含:一個數字、一個字母、一個標點符號。
  5. 與舊密碼差異 ≥ 3 字元(位置或字元不同)。

核心程式碼節錄

CREATE OR REPLACE FUNCTION sys.verify_function (
  username     VARCHAR2,
  password     VARCHAR2,
  old_password VARCHAR2
) RETURN BOOLEAN IS
  v_digit_arr  VARCHAR2(20) := '0123456789';
  v_char_arr   VARCHAR2(52) := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  v_punct_arr  VARCHAR2(25) := '!"#$%&()``*+,-/:;<=>?_';
  v_has_digit  BOOLEAN := FALSE;
  v_has_char   BOOLEAN := FALSE;
  v_has_punct  BOOLEAN := FALSE;
  v_diff_cnt   INTEGER := 0;
BEGIN
  -- 1. 與使用者名比對
  IF LOWER(password) = LOWER(username) THEN
    RAISE_APPLICATION_ERROR(-20001, 'Password same as user');
  END IF;

  -- 2. 長度
  IF LENGTH(password) < 8 THEN
    RAISE_APPLICATION_ERROR(-20002, 'Password length less than 8');
  END IF;

  -- 3. 字典弱密碼
  IF LOWER(password) IN ('welcome','database','account','user','password','oracle','computer','abcd') THEN
    RAISE_APPLICATION_ERROR(-20003, 'Password too simple');
  END IF;

  -- 4. 複雜度:數字、字母、標點
  FOR i IN 1..LENGTH(password) LOOP
    IF INSTR(v_digit_arr, SUBSTR(password,i,1)) > 0 THEN v_has_digit := TRUE;
    ELSIF INSTR(v_char_arr, SUBSTR(password,i,1)) > 0 THEN v_has_char := TRUE;
    ELSIF INSTR(v_punct_arr, SUBSTR(password,i,1)) > 0 THEN v_has_punct := TRUE;
    END IF;
  END LOOP;
  IF NOT (v_has_digit AND v_has_char AND v_has_punct) THEN
    RAISE_APPLICATION_ERROR(-20004, 'Password must contain digit, char, punctuation');
  END IF;

  -- 5. 與舊密碼差異
  IF old_password IS NOT NULL THEN
    v_diff_cnt := ABS(LENGTH(old_password) - LENGTH(password));
    FOR i IN 1..LEAST(LENGTH(password), LENGTH(old_password)) LOOP
      IF SUBSTR(password,i,1) != SUBSTR(old_password,i,1) THEN v_diff_cnt := v_diff_cnt + 1; END IF;
    END LOOP;
    IF v_diff_cnt < 3 THEN
      RAISE_APPLICATION_ERROR(-20005, 'Password must differ by at least 3 characters');
    END IF;
  END IF;

  RETURN TRUE;
END;
/

套用至 Profile

ALTER PROFILE default LIMIT
  PASSWORD_VERIFY_FUNCTION verify_function
  PASSWORD_LIFE_TIME 90
  PASSWORD_GRACE_TIME 7
  FAILED_LOGIN_ATTEMPTS 5
  PASSWORD_LOCK_TIME 1;

測試驗證

-- 應失敗:長度不足
ALTER USER scott IDENTIFIED BY abc123;
-- ORA-28003: password verification failed: Password length less than 8

-- 應成功
ALTER USER scott IDENTIFIED BY Str0ng!Pass;

進階擴充建議

  • 整合 DBMS_CRYPTO 檢測鍵盤連續鍵(如 qwerty、123456)。
  • 對接企業密碼歷史表,防止重複使用近 N 代密碼。
  • 12c+ 可使用 PASSWORD_VERIFY_FUNCTION 回傳 VARCHAR2 錯誤訊息,支援多語系。

結語

密碼驗證函數是資料庫第一道防線。建議依合規需求(PCI-DSS、GDPR、等保)調整規則,並納入 CI/CD 自動化測試,確保策略生效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved