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

ORA-01017
2026년 05월 21일 | Oracle DBA 가이드

📌 이 글에서 다루는 내용

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

# ORA-01017 완벽 해결 가이드: invalid username/password; logon denied


ORA-01017란?

ORA-01017은 Oracle 데이터베이스에 접속을 시도할 때 입력한 사용자명(Username) 또는 비밀번호(Password)가 올바르지 않아 로그인이 거부될 때 발생하는 에러입니다. 단순히 비밀번호를 잘못 입력한 경우뿐만 아니라, 계정 잠금, 대소문자 구분 설정, 잘못된 접속 문자열 등 다양한 원인으로 발생할 수 있어 실무에서 가장 빈번하게 마주치는 에러 중 하나입니다. 특히 Oracle 11g 이후부터 비밀번호 대소문자 구분(Case Sensitive)이 기본값으로 활성화되어, 기존 방식으로 접속하던 개발자나 DBA가 업그레이드 후 이 에러를 겪는 사례가 매우 많습니다.


주요 발생 원인

1. 비밀번호 대소문자 구분 문제 (Case Sensitivity)

Oracle 11g부터 SEC_CASE_SENSITIVE_LOGON 파라미터가 기본적으로 TRUE로 설정되어 비밀번호가 대소문자를 구분합니다. 이전 버전(10g 이하)에서 마이그레이션하거나, 비밀번호 설정 당시의 대소문자를 정확히 기억하지 못하는 경우 로그인에 실패하게 됩니다.

2. 계정 잠금(Account Lock) 상태

비밀번호를 여러 번 틀리거나 프로파일의 FAILED_LOGIN_ATTEMPTS 설정값을 초과하면 계정이 자동으로 잠깁니다. 잠긴 계정은 올바른 비밀번호를 입력해도 ORA-01017과 함께 접속이 거부되며, 이 경우 ORA-28000 에러가 함께 발생하기도 합니다.

3. 비밀번호 만료(Password Expired)

Oracle 프로파일의 PASSWORD_LIFE_TIME 설정에 의해 비밀번호 유효기간이 지난 경우 로그인이 차단됩니다. 특히 DEFAULT 프로파일의 PASSWORD_LIFE_TIME이 180일로 설정된 운영 환경에서 주기적으로 발생할 수 있으며, 이 경우 ORA-28001 에러와 함께 나타납니다.

4. 잘못된 접속 문자열 또는 환경변수 설정

JDBC, Python, Shell Script 등 애플리케이션에서 접속 문자열 내 사용자명이나 비밀번호가 잘못 설정된 경우 발생합니다. 특히 비밀번호에 특수문자(@, !, # 등)가 포함된 경우 이스케이프 처리를 하지 않아 접속에 실패하는 사례가 매우 흔합니다.

5. 잘못된 데이터베이스 링크(Database Link) 설정

DB Link를 통해 원격 데이터베이스에 접속할 때, 원격 DB의 계정 정보가 변경되었음에도 DB Link가 이전 정보를 그대로 사용하고 있는 경우 ORA-01017이 발생합니다. 비밀번호 변경 후 관련 DB Link를 재생성하지 않은 경우가 대표적입니다.


해결 방법

① 비밀번호 대소문자 구분 확인 및 해결

현재 대소문자 구분 설정을 확인하고, 필요 시 임시로 비활성화할 수 있습니다.

-- 현재 대소문자 구분 설정 확인
SHOW PARAMETER SEC_CASE_SENSITIVE_LOGON;

-- 대소문자 구분 비활성화 (임시 조치, 보안상 권장하지 않음)
ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE;

-- 비밀번호를 명확하게 대소문자 포함하여 재설정
ALTER USER scott IDENTIFIED BY "NewPass#2024";

-- 설정 복원 (보안을 위해 반드시 원복)
ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = TRUE;

> ⚠️ 대소문자 구분 비활성화는 보안 취약점을 유발할 수 있으므로, 가급적 비밀번호를 재설정하는 방향으로 해결하는 것을 권장합니다.


② 계정 잠금 해제

-- 계정 잠금 여부 확인
SELECT username, account_status, lock_date, expiry_date
FROM dba_users
WHERE username = 'SCOTT';

-- 계정 잠금 해제
ALTER USER scott ACCOUNT UNLOCK;

-- 잠금 해제 후 비밀번호도 함께 재설정 (권장)
ALTER USER scott IDENTIFIED BY "NewSecurePass#1" ACCOUNT UNLOCK;

-- 프로파일의 FAILED_LOGIN_ATTEMPTS 설정 확인
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_name = 'FAILED_LOGIN_ATTEMPTS'
ORDER BY profile;

③ 비밀번호 만료 해결

-- 비밀번호 만료 상태 확인
SELECT username, account_status, expiry_date
FROM dba_users
WHERE account_status LIKE '%EXPIRED%';

-- 비밀번호 재설정으로 만료 해제
ALTER USER scott IDENTIFIED BY "NewPass#2024";

-- 특정 계정의 비밀번호 만료 기한 무제한으로 변경 (서비스 계정 권장)
-- 먼저 전용 프로파일 생성
CREATE PROFILE app_service_profile LIMIT
  PASSWORD_LIFE_TIME UNLIMITED
  FAILED_LOGIN_ATTEMPTS 10
  PASSWORD_LOCK_TIME 1/24;

-- 프로파일 적용
ALTER USER app_user PROFILE app_service_profile;

-- 적용 결과 확인
SELECT username, profile FROM dba_users WHERE username = 'APP_USER';

④ 특수문자가 포함된 비밀번호 접속 방법

비밀번호에 특수문자가 포함된 경우, sqlplus에서는 큰따옴표로 감싸서 처리합니다.

-- sqlplus 접속 시 특수문자 포함 비밀번호 처리
-- 잘못된 방법 (@ 문자가 TNS 서비스명으로 해석될 수 있음)
-- sqlplus scott/Pass@word@ORCL

-- 올바른 방법 1: 큰따옴표 사용
-- sqlplus scott/"Pass@word#1"@ORCL

-- 올바른 방법 2: 접속 후 비밀번호를 특수문자 없이 변경
ALTER USER scott IDENTIFIED BY "SimplePass2024";

-- JDBC 접속 문자열에서의 처리 (비밀번호에 @ 포함 시)
-- jdbc:oracle:thin:scott/Pass%40word@//hostname:1521/ORCL
-- %40은 @의 URL 인코딩 값

-- 비밀번호 복잡도 정책 확인
SELECT *
FROM dba_profiles
WHERE resource_name LIKE 'PASSWORD%'
  AND profile = 'DEFAULT'
ORDER BY resource_name;

⑤ DB Link 재생성

-- 현재 DB Link 목록 확인
SELECT db_link, username, host
FROM dba_db_links
WHERE owner = 'SCOTT';

-- 기존 DB Link 삭제
DROP DATABASE LINK remote_db_link;

-- DB Link 재생성 (변경된 비밀번호로)
CREATE DATABASE LINK remote_db_link
  CONNECT TO remote_user IDENTIFIED BY "NewRemotePass#1"
  USING 'REMOTE_DB_TNS';

-- DB Link 접속 테스트
SELECT * FROM dual@remote_db_link;

-- 공용(PUBLIC) DB Link 재생성 (DBA 권한 필요)
CREATE PUBLIC DATABASE LINK pub_remote_link
  CONNECT TO remote_user IDENTIFIED BY "NewRemotePass#1"
  USING 'REMOTE_DB_TNS';

⑥ 사용자 계정 및 권한 전체 점검 쿼리

-- 계정 상태 전체 점검 (DBA 용)
SELECT
    u.username,
    u.account_status,
    u.lock_date,
    u.expiry_date,
    u.profile,
    u.created,
    p.limit AS failed_login_limit
FROM dba_users u
JOIN dba_profiles p ON u.profile = p.profile
WHERE p.resource_name = 'FAILED_LOGIN_ATTEMPTS'
ORDER BY u.username;

-- 최근 접속 실패 이력 확인 (감사 로그 활성화 필요)
SELECT os_username, username, userhost, timestamp, returncode, action_name
FROM dba_audit_trail
WHERE returncode = 1017   -- ORA-01017 에러 코드
  AND timestamp >= SYSDATE - 7
ORDER BY timestamp DESC;

예방 방법

1. 서비스 계정(Application Account) 전용 프로파일 관리

운영 환경에서 애플리케이션이 사용하는 서비스 계정은 일반 사용자 계정과 분리된 전용 프로파일을 적용해야 합니다. 비밀번호 만료와 잠금으로 인한 장애를 방지하기 위해 PASSWORD_LIFE_TIMEFAILED_LOGIN_ATTEMPTS를 업무 특성에 맞게 설정하고, 변경 이력을 문서화하여 관리하십시오.

📚 Oracle 에러 코드 시리즈

ORA 에러를 번호 순서대로 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

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

댓글 남기기