【Oracle】パスワードポリシーをカスタマイズする方法|PASSWORD_VERIFY_FUNCTION・複雑性チェック・履歴管理・カスタム関数まで解説

【Oracle】パスワードポリシーをカスタマイズする方法|PASSWORD_VERIFY_FUNCTION・複雑性チェック・履歴管理・カスタム関数まで解説 Oracle

Oracle のパスワードポリシーはプロファイルで管理されます。有効期限(PASSWORD_LIFE_TIME)や履歴(PASSWORD_REUSE_TIME / MAX)はパラメータで設定できますが、「英数字 + 記号を必須にする」「ユーザー名をパスワードに使用禁止にする」といった複雑性チェックPASSWORD_VERIFY_FUNCTION で制御します。

本記事では、Oracle 提供の検証関数、カスタム検証関数の自作パスワード履歴の管理環境別のプロファイル設計例まで解説します。

この記事でわかること
・PASSWORD_VERIFY_FUNCTION の仕組みと設定方法
・Oracle 提供の検証関数(ORA12C_VERIFY_FUNCTION / ORA12C_STRONG_VERIFY_FUNCTION)のルール
・カスタム検証関数を PL/SQL で自作する方法
・PASSWORD_REUSE_TIME / PASSWORD_REUSE_MAX による履歴管理
・パスワードパラメータの全一覧表
・開発 / 本番 / PCI DSS 準拠のプロファイル設計例
スポンサーリンク

パスワード関連パラメータの全一覧

パラメータ デフォルト 説明
PASSWORD_LIFE_TIME 180 パスワードの有効期間(日)
PASSWORD_GRACE_TIME 7 期限切れ後の猶予期間(日)
PASSWORD_REUSE_TIME UNLIMITED 同じパスワードを再利用できるまでの日数
PASSWORD_REUSE_MAX UNLIMITED 同じパスワードを再利用できるまでの変更回数
FAILED_LOGIN_ATTEMPTS 10 連続失敗でロックされるまでの回数
PASSWORD_LOCK_TIME 1 ロック後の自動解除までの日数(1/24 = 1 時間)
PASSWORD_VERIFY_FUNCTION NULL パスワード複雑性チェック関数。NULL = チェックなし
PASSWORD_ROLLOVER_TIME UNLIMITED(21c+) 旧パスワードでもログイン可能な移行期間

有効期限の詳しい設定方法は「パスワードの有効期限を無制限にする方法」を参照してください。

PASSWORD_VERIFY_FUNCTION(複雑性チェック)

PASSWORD_VERIFY_FUNCTION にパスワード検証関数を設定すると、ALTER USER / CREATE USER でパスワードを設定するたびに関数が自動的に呼び出され、ルールに合致しないパスワードは拒否されます。

Oracle 提供の検証関数

関数名 バージョン ルール
VERIFY_FUNCTION_11G 11g 最低 8 文字、英字 + 数字 + 記号、ユーザー名と異なる、前回と 3 文字以上異なる
ORA12C_VERIFY_FUNCTION 12c+ 最低 8 文字、英字 + 数字、ユーザー名 / DB名を含まない、前回と 3 文字以上異なる
ORA12C_STRONG_VERIFY_FUNCTION 12c+ 最低 9 文字、大文字 + 小文字 + 数字 + 記号、ユーザー名 / DB 名を含まない
SQL(Oracle 提供の検証関数をインストール)
-- 検証関数のインストール(SYS ユーザーで実行、初回のみ)
-- 11g 用
@$ORACLE_HOME/rdbms/admin/utlpwdmg.sql

-- 12c+ 用(utlpwdmg.sql に ORA12C_VERIFY_FUNCTION も含まれる)
@$ORACLE_HOME/rdbms/admin/catpvf.sql
SQL(検証関数をプロファイルに設定)
-- ORA12C_VERIFY_FUNCTION を DEFAULT プロファイルに設定
ALTER PROFILE DEFAULT LIMIT
    PASSWORD_VERIFY_FUNCTION ORA12C_VERIFY_FUNCTION;

-- STRONG 版を設定(記号必須)
ALTER PROFILE DEFAULT LIMIT
    PASSWORD_VERIFY_FUNCTION ORA12C_STRONG_VERIFY_FUNCTION;

-- 検証関数を無効化(チェックなし)
ALTER PROFILE DEFAULT LIMIT
    PASSWORD_VERIFY_FUNCTION NULL;

-- 現在の設定を確認
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_VERIFY_FUNCTION'
ORDER BY profile;
SQL(検証関数の動作テスト)
-- 弱いパスワードで ALTER USER を実行するとエラーになる
ALTER USER test_user IDENTIFIED BY test;
-- ORA-28003: password verification for the specified password failed
-- ORA-20001: Password length less than 8

-- 複雑なパスワードなら成功
ALTER USER test_user IDENTIFIED BY Str0ng_P@ss2026;

カスタム検証関数を作成する

Oracle 提供の関数では足りない場合、PL/SQL で独自の検証ルールを実装できます。関数のインタフェース(引数と戻り値)は Oracle が定めた形式に従う必要があります。

SQL(カスタム検証関数の例)
-- SYS ユーザーで実行
CREATE OR REPLACE FUNCTION custom_pwd_verify(
    username     VARCHAR2,
    password     VARCHAR2,
    old_password VARCHAR2
) RETURN BOOLEAN IS
BEGIN
    -- ルール(1): 最低 10 文字
    IF LENGTH(password) < 10 THEN
        RAISE_APPLICATION_ERROR(-20001, '10 文字以上で設定してください');
    END IF;

    -- ルール(2): 大文字を 1 文字以上含む
    IF NOT REGEXP_LIKE(password, '[A-Z]') THEN
        RAISE_APPLICATION_ERROR(-20002, '大文字を 1 文字以上含めてください');
    END IF;

    -- ルール(3): 小文字を 1 文字以上含む
    IF NOT REGEXP_LIKE(password, '[a-z]') THEN
        RAISE_APPLICATION_ERROR(-20003, '小文字を 1 文字以上含めてください');
    END IF;

    -- ルール(4): 数字を 1 文字以上含む
    IF NOT REGEXP_LIKE(password, '[0-9]') THEN
        RAISE_APPLICATION_ERROR(-20004, '数字を 1 文字以上含めてください');
    END IF;

    -- ルール(5): 記号を 1 文字以上含む
    IF NOT REGEXP_LIKE(password, '[!@#$%^&*()_+\-=]') THEN
        RAISE_APPLICATION_ERROR(-20005, '記号を 1 文字以上含めてください');
    END IF;

    -- ルール(6): ユーザー名をパスワードに含まない
    IF UPPER(password) LIKE '%' || UPPER(username) || '%' THEN
        RAISE_APPLICATION_ERROR(-20006, 'ユーザー名をパスワードに含めないでください');
    END IF;

    -- ルール(7): 前回のパスワードと異なる(old_password が NULL でない場合)
    IF old_password IS NOT NULL AND password = old_password THEN
        RAISE_APPLICATION_ERROR(-20007, '前回と同じパスワードは使用できません');
    END IF;

    RETURN TRUE;
END;
/

-- カスタム関数をプロファイルに設定
ALTER PROFILE prod_profile LIMIT
    PASSWORD_VERIFY_FUNCTION custom_pwd_verify;

カスタム関数の必須インタフェース

引数 内容
username VARCHAR2 パスワードを変更するユーザー名
password VARCHAR2 新しいパスワード
old_password VARCHAR2 古いパスワード(ALTER USER 時のみ。CREATE USER 時は NULL)
カスタム関数は SYS スキーマに作成する
PASSWORD_VERIFY_FUNCTION に設定する関数はSYS スキーマに作成する必要があります。他のスキーマに作成するとプロファイル設定時にエラーになります。
カスタム関数に追加できるルール例
・辞書攻撃対策: 一般的な英単語(password, oracle, admin 等)を禁止
・連続文字禁止: aaa, 111, abc のような連続を禁止
・DB 名禁止: V$DATABASE.NAME をパスワードに含むことを禁止
・最低変更文字数: 前回のパスワードと N 文字以上異なることを要求

パスワード履歴の管理(再利用制限)

パラメータ 意味 設定例 効果
PASSWORD_REUSE_TIME 同じパスワードを再利用できるまでの日数 365 1 年間は同じパスワードを再設定できない
PASSWORD_REUSE_MAX 同じパスワードを再利用できるまでの変更回数 12 12 回変更するまで同じパスワードに戻せない
SQL(パスワード履歴の設定)
-- 1 年間 かつ 12 回変更するまで再利用不可
ALTER PROFILE prod_profile LIMIT
    PASSWORD_REUSE_TIME 365
    PASSWORD_REUSE_MAX  12;

-- 再利用制限を無効化
ALTER PROFILE dev_profile LIMIT
    PASSWORD_REUSE_TIME UNLIMITED
    PASSWORD_REUSE_MAX  UNLIMITED;
両方が UNLIMITED だと再利用制限が無効
PASSWORD_REUSE_TIME と PASSWORD_REUSE_MAX の両方が UNLIMITED の場合、以前のパスワードをすぐに再設定できます。片方だけを UNLIMITED にしても、もう片方の制限は有効です。本番環境では両方に値を設定してください。

環境別のプロファイル設計例

開発環境(パスワード制限を緩和)

SQL
CREATE PROFILE dev_profile LIMIT
    PASSWORD_LIFE_TIME        UNLIMITED
    PASSWORD_GRACE_TIME       UNLIMITED
    PASSWORD_REUSE_TIME       UNLIMITED
    PASSWORD_REUSE_MAX        UNLIMITED
    FAILED_LOGIN_ATTEMPTS     UNLIMITED
    PASSWORD_VERIFY_FUNCTION  NULL;

本番環境(標準セキュリティ)

SQL
CREATE PROFILE prod_profile LIMIT
    PASSWORD_LIFE_TIME        90
    PASSWORD_GRACE_TIME       7
    PASSWORD_REUSE_TIME       365
    PASSWORD_REUSE_MAX        12
    FAILED_LOGIN_ATTEMPTS     5
    PASSWORD_LOCK_TIME        1/24    -- 1 時間
    PASSWORD_VERIFY_FUNCTION  ORA12C_VERIFY_FUNCTION;

PCI DSS 準拠(強化セキュリティ)

SQL
-- PCI DSS Requirement 8 に準拠
CREATE PROFILE pci_profile LIMIT
    PASSWORD_LIFE_TIME        90      -- 90 日で期限切れ
    PASSWORD_GRACE_TIME       0       -- 猶予なし(即時ロック)
    PASSWORD_REUSE_TIME       365     -- 1 年間再利用不可
    PASSWORD_REUSE_MAX        4       -- 4 世代は再利用不可
    FAILED_LOGIN_ATTEMPTS     6       -- 6 回で自動ロック
    PASSWORD_LOCK_TIME        1/48    -- 30 分ロック
    PASSWORD_VERIFY_FUNCTION  ORA12C_STRONG_VERIFY_FUNCTION;
要件 開発 本番 PCI DSS
有効期限 UNLIMITED 90 日 90 日(GRACE なし)
複雑性チェック なし ORA12C_VERIFY ORA12C_STRONG_VERIFY
履歴(再利用不可期間) なし 1 年 1 年
ロックまでの失敗回数 UNLIMITED 5 回 6 回
ロック時間 1 時間 30 分

現在のパスワードポリシーを確認する

SQL(プロファイルのパスワード設定を一覧)
-- 全プロファイルのパスワード設定
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_type = 'PASSWORD'
ORDER BY profile, resource_name;

-- ユーザーごとのプロファイル割り当て
SELECT username, profile, account_status
FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
ORDER BY profile, username;

-- PASSWORD_VERIFY_FUNCTION の関数本体を確認
SELECT text FROM dba_source
WHERE owner = 'SYS' AND name = 'ORA12C_VERIFY_FUNCTION'
ORDER BY line;

PASSWORD_ROLLOVER_TIME(21c+: パスワード移行期間)

Oracle 21c 以降では PASSWORD_ROLLOVER_TIME を設定すると、パスワード変更後も一定期間は旧パスワードでログイン可能になります。アプリケーションのパスワード変更のローリングデプロイに便利です。

SQL(PASSWORD_ROLLOVER_TIME)
-- パスワード変更後、24 時間は旧パスワードでもログイン可能
ALTER PROFILE app_profile LIMIT
    PASSWORD_ROLLOVER_TIME 1;  -- 1 日

-- 無効化
ALTER PROFILE app_profile LIMIT
    PASSWORD_ROLLOVER_TIME 0;

よくある質問

QPASSWORD_VERIFY_FUNCTION に NULL を設定するとどうなりますか?
Aパスワードの複雑性チェックが完全に無効化されます。1 文字のパスワードやユーザー名と同じパスワードも設定可能になります。開発環境ではNULL でも問題ありませんが、本番環境では必ず検証関数を設定してください。
QOracle 提供の検証関数はどこにありますか?
A$ORACLE_HOME/rdbms/admin/catpvf.sql(12c+)に定義されています。このスクリプトを SYS ユーザーで実行すると ORA12C_VERIFY_FUNCTION / ORA12C_STRONG_VERIFY_FUNCTION が作成されます。11g 以前は utlpwdmg.sql です。
Qカスタム検証関数はどのスキーマに作成しますか?
ASYS スキーマに作成する必要があります。他のスキーマ(HR / APP_OWNER 等)に作成しても、プロファイルの PASSWORD_VERIFY_FUNCTION には SYS の関数しか指定できません。
QPASSWORD_REUSE_TIME だけ設定して PASSWORD_REUSE_MAX を UNLIMITED にしたらどうなりますか?
APASSWORD_REUSE_TIME の日数だけが有効になります。例えば REUSE_TIME=365 / REUSE_MAX=UNLIMITED なら「365 日経過すれば変更回数に関係なく再利用可能」です。ただし両方が UNLIMITED だと再利用制限は無効になります。
Q検証関数のエラーメッセージをカスタマイズできますか?
Aはい。カスタム関数内の RAISE_APPLICATION_ERROR のメッセージを自由に変更できます。日本語のエラーメッセージを設定すれば、パスワード変更時に具体的なルール違反の内容が表示されます。
Qパスワード変更時に old_password が NULL になるのはなぜですか?
ACREATE USER での初回パスワード設定時と、DBA が ALTER USER で他ユーザーのパスワードを変更する場合、old_password は NULL になります。ユーザー自身が PASSWORD コマンドで変更する場合のみ old_password が渡されます。カスタム関数では old_password IS NULL のケースを考慮してください。

まとめ

パスワードポリシーのカスタマイズ要点をまとめます。

やりたいこと 方法
パスワードの複雑性チェックを有効化 ALTER PROFILE … LIMIT PASSWORD_VERIFY_FUNCTION ORA12C_VERIFY_FUNCTION
より厳しいチェック(記号必須) PASSWORD_VERIFY_FUNCTION ORA12C_STRONG_VERIFY_FUNCTION
独自ルールでチェック SYS にカスタム PL/SQL 関数を作成して指定
パスワードの再利用を制限 PASSWORD_REUSE_TIME / PASSWORD_REUSE_MAX
複雑性チェックを無効化 PASSWORD_VERIFY_FUNCTION NULL
パスワード移行期間を設定(21c+) PASSWORD_ROLLOVER_TIME N
現在のポリシーを確認 SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_type=’PASSWORD’

パスワード有効期限の設定は「パスワードの有効期限を無制限にする方法」、プロファイルの全パラメータは「ユーザープロファイル完全ガイド」、接続制限は「ユーザーごとに接続制限を設定する方法」も併せて参照してください。