Oracle ORA-28003 오류 원인과 해결 방법 완벽 가이드

ORA-28003
2026년 10월 03일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-28003 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-28003 password verification for the specified password failed 는?

ORA-28003 에러는 Oracle 데이터베이스에서 사용자가 비밀번호를 변경하거나 생성할 때, 설정된 비밀번호 검증 함수(Password Verification Function)의 조건을 충족하지 못할 경우 발생하는 에러입니다. Oracle Profile에 PASSWORD_VERIFY_FUNCTION이 지정되어 있고, 입력한 비밀번호가 해당 함수에서 정의한 복잡성 규칙(최소 길이, 특수문자 포함, 대소문자 혼용, 이전 비밀번호와의 유사도 등)을 통과하지 못하면 이 에러가 트리거됩니다. 특히 Oracle 12c 이상 버전에서는 기본 보안 정책이 강화되어 DBA가 명시적으로 설정하지 않아도 ORA12C_STRONG_VERIFY_FUNCTION이 적용될 수 있어, 단순한 비밀번호 설정 시 자주 마주치게 됩니다.


주요 발생 원인

  • 비밀번호 복잡성 규칙 미충족 (가장 흔한 원인)

Oracle Profile에 등록된 비밀번호 검증 함수가 요구하는 최소 조건(길이, 숫자 포함, 대문자 포함, 특수문자 포함 등)을 입력한 비밀번호가 만족하지 못할 때 발생합니다. 예를 들어 ORA12C_STRONG_VERIFY_FUNCTION은 최소 9자 이상, 대문자 1개 이상, 소문자 1개 이상, 숫자 1개 이상, 특수문자 1개 이상을 요구합니다. 단순히 password123이나 oracle과 같은 비밀번호를 설정하려 할 때 이 에러가 발생합니다.

  • 커스텀 비밀번호 검증 함수의 로직 오류 또는 과도한 제약

DBA가 직접 작성한 커스텀 검증 함수 내에 예상치 못한 로직 오류가 있거나, 너무 엄격한 제약 조건이 걸려 있어 사실상 어떤 비밀번호도 통과하지 못하는 상황이 발생할 수 있습니다. 함수 내부에서 예외 처리가 잘못 되어 있거나, 이전 비밀번호와의 비교 로직에서 버그가 있는 경우에도 이 에러가 지속적으로 발생합니다. 이 경우는 단순히 비밀번호를 바꾸는 것으로 해결되지 않으며 함수 자체를 점검해야 합니다.

  • Profile에 검증 함수가 적용되어 있음을 인지하지 못한 상태에서의 비밀번호 변경

개발환경 또는 운영환경 마이그레이션 후, 혹은 보안 정책 강화 이후 Profile이 변경되었는데 담당자가 이를 인지하지 못한 채 기존 방식대로 단순한 비밀번호를 설정하려 할 때 발생합니다. DEFAULT Profile에 검증 함수가 새로 추가되었거나, 사용자에게 할당된 Profile 자체가 변경된 경우가 대표적입니다. 이는 특히 여러 팀이 함께 운영하는 환경에서 커뮤니케이션 오류로 인해 빈번하게 발생합니다.


해결 방법

원인 1: 비밀번호 복잡성 규칙 확인 및 복잡한 비밀번호로 변경

먼저 현재 사용자에게 적용된 Profile과 검증 함수를 확인합니다.

-- 사용자에게 할당된 Profile 확인
SELECT USERNAME, PROFILE
FROM DBA_USERS
WHERE USERNAME = 'TARGET_USER';

-- Profile에 설정된 비밀번호 검증 함수 확인
SELECT PROFILE, RESOURCE_NAME, LIMIT
FROM DBA_PROFILES
WHERE RESOURCE_NAME = 'PASSWORD_VERIFY_FUNCTION'
  AND PROFILE IN (
    SELECT PROFILE FROM DBA_USERS WHERE USERNAME = 'TARGET_USER'
  );

확인 후 복잡성 규칙을 충족하는 비밀번호로 변경합니다.

-- 복잡성 규칙을 충족하는 비밀번호로 변경 (대문자+소문자+숫자+특수문자)
ALTER USER TARGET_USER IDENTIFIED BY "MyP@ssw0rd#2024";

원인 2: 커스텀 검증 함수 점검 및 수정

현재 적용된 검증 함수의 소스코드를 확인하고 테스트합니다.

-- 검증 함수 소스 확인
SELECT TEXT
FROM DBA_SOURCE
WHERE NAME = 'YOUR_VERIFY_FUNCTION'
  AND TYPE = 'FUNCTION'
ORDER BY LINE;

-- 검증 함수 직접 테스트 (SYS 권한 필요)
-- 함수가 TRUE를 반환하면 검증 통과
DECLARE
  v_result BOOLEAN;
BEGIN
  v_result := YOUR_VERIFY_FUNCTION(
    username    => 'TARGET_USER',
    password    => 'TestP@ss1234',
    old_password => NULL
  );
  IF v_result THEN
    DBMS_OUTPUT.PUT_LINE('Password verification PASSED');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Password verification FAILED');
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/

긴급 상황에서 임시로 검증 함수를 비활성화해야 할 경우 (운영 환경에서는 신중히 사용):

-- 임시로 검증 함수 비활성화 (DBA 권한 필요)
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION NULL;

-- 비밀번호 변경 후 다시 복원
ALTER USER TARGET_USER IDENTIFIED BY "NewSecureP@ss1!";

-- 검증 함수 재활성화
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ORA12C_STRONG_VERIFY_FUNCTION;

원인 3: Profile 현황 전체 점검

-- 전체 Profile 및 비밀번호 정책 현황 조회
SELECT P.PROFILE,
       P.RESOURCE_NAME,
       P.LIMIT,
       COUNT(U.USERNAME) AS USER_COUNT
FROM DBA_PROFILES P
LEFT JOIN DBA_USERS U ON U.PROFILE = P.PROFILE
WHERE P.RESOURCE_NAME IN (
  'PASSWORD_VERIFY_FUNCTION',
  'PASSWORD_LIFE_TIME',
  'PASSWORD_REUSE_TIME',
  'PASSWORD_REUSE_MAX',
  'PASSWORD_LOCK_TIME',
  'FAILED_LOGIN_ATTEMPTS'
)
GROUP BY P.PROFILE, P.RESOURCE_NAME, P.LIMIT
ORDER BY P.PROFILE, P.RESOURCE_NAME;

-- 특정 사용자의 Profile을 변경 (검증이 덜 엄격한 Profile로)
ALTER USER TARGET_USER PROFILE NEW_PROFILE_NAME;

Oracle 제공 표준 검증 함수를 재생성해야 할 경우:

-- Oracle 제공 비밀번호 검증 스크립트 실행 (경로는 버전마다 다를 수 있음)
-- $ORACLE_HOME/rdbms/admin/utlpwdmg.sql
@?/rdbms/admin/utlpwdmg.sql

-- 적용 확인
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM DBA_OBJECTS
WHERE OBJECT_NAME IN (
  'VERIFY_FUNCTION',
  'ORA12C_VERIFY_FUNCTION',
  'ORA12C_STRONG_VERIFY_FUNCTION'
);

예방 방법

  • 비밀번호 정책 문서화 및 전사 공유

DB 환경에 적용된 모든 Profile의 비밀번호 정책(검증 함수, 최소 길이, 만료 기간 등)을 문서화하고, DBA뿐 아니라 개발팀, 운영팀과도 공유하는 것이 중요합니다. 특히 신규 프로젝트 시작이나 시스템 마이그레이션 시점에는 반드시 비밀번호 정책을 재확인하고 관련자에게 공지해야 합니다. 아래 쿼리를 정기적으로 실행하여 정책 현황을 모니터링하는 것을 권장합니다.

-- 정기 모니터링용 쿼리: 비밀번호 정책 현황 스냅샷
SELECT PROFILE,
       MAX(CASE WHEN RESOURCE_NAME = 'PASSWORD_VERIFY_FUNCTION' THEN LIMIT END) AS VERIFY_FUNCTION,
       MAX(CASE WHEN RESOURCE_NAME = 'PASSWORD_LIFE_TIME' THEN LIMIT END) AS LIFE_TIME,
       MAX(CASE WHEN RESOURCE_NAME = 'FAILED_LOGIN_ATTEMPTS' THEN LIMIT END) AS MAX_FAILED_LOGIN,
       MAX(CASE WHEN RESOURCE_NAME = 'PASSWORD_LOCK_TIME' THEN LIMIT END) AS LOCK_TIME
FROM DBA_PROFILES
WHERE RESOURCE_NAME IN (
  'PASSWORD_VERIFY_FUNCTION','PASSWORD_LIFE_TIME',
  'FAILED_LOGIN_ATTEMPTS','PASSWORD_LOCK_TIME'
)
GROUP BY PROFILE
ORDER BY PROFILE;
  • 검증 함수 변경 시 반드시 테스트 환경에서 먼저 검증

커스텀 비밀번호 검증 함수를 수정하거나 새로 배포할 때는 반드시 개발/스테이징 환경에서 충분히 테스트한 후 운영 환경에 적용해야 합니다. 함수 배포 후에는 실제 비밀번호 변경 테스트를 수행하여 정상 동작 여부를 확인하고, 변경 이력을 관리 대장에 기록해 두어야 합니다. 또한 검증 함수 내부에는 반드시 명확한 에러 메시지를 포함시켜 사용자가 어떤 조건을 충족시키지 못했는지 인지할 수 있도록 해야 합니다.

-- 좋은 커스텀 검증 함수 작성 예시 (핵심 골격)
CREATE OR REPLACE FUNCTION custom_verify_function(
  username     VARCHAR2,
  password     VARCHAR2,
  old_password VARCHAR2
) RETURN BOOLEAN IS
  v_min_length  NUMBER := 10;
  v_digit_count NUMBER := 0;
BEGIN
  -- 최소 길이 검사
  IF LENGTH(password) < v_min_length THEN
    RAISE_APPLICATION_ERROR(-20001,
      '비밀번호는 최소 ' || v_min_length || '자 이상이어야 합니다.');
  END IF;

  -- 숫자 포함 검사
  FOR i IN 1..LENGTH(password) LOOP
    IF SUBSTR(password, i, 1) BETWEEN '0' AND '9' THEN
      v_digit_count := v_digit_count + 1;
    END IF;
  END LOOP;

  IF v_digit_count = 0 THEN
    RAISE_APPLICATION_ERROR(-20002,
      '비밀번호에 숫자가 최소 1개 이상 포함되어야 합니다.');
  END IF;

  RETURN TRUE;
EXCEPTION
  WHEN OTHERS THEN
    RAISE;
END;
/

관련 에러

  • ORA-28001: 비밀번호 만료(PASSWORD_LIFE_TIME 초과) 시 발생. 비밀번호 변경 시 ORA-28003과 연달아 발생하는 경우가 많습니다.
  • ORA-28002: 비밀번호 만료 임박 경고. 변경 유도 시 ORA-28003과 함께 마주칠 수 있습니다.
  • ORA-28007: 비밀번호 재사용 정책(PASSWORD_REUSE_TIME, PASSWORD_REUSE_MAX) 위반 시 발생. 검증 함수 통과 후에도 이 에러가 발생할 수 있습니다.
  • ORA-28011: 계정 만료로 인한 비밀번호 변경 강제 시 발생. 비밀번호 변경 과정에서 ORA-28003과 함께 발생할 수 있습니다.
  • ORA-20001 ~ ORA-20999: 커스텀 검증 함수 내에서 RAISE_APPLICATION_ERROR로 발생시키는 사용자 정의 에러. ORA-28003의 실제 원인 메시지를 담고 있는 경우가 많습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기