본문 바로가기

정규식 비밀번호 검증 패턴 총정리 - 실무에서 바로 쓰는 코드 예제와 보안 기준까지 한번에

회원가입 폼에 바로 붙여 쓸 수 있는 정규식 비밀번호 검증 패턴 5가지를 정리했습니다. 전방탐색 문법 해설부터 자바스크립트 적용 코드, NIST 보안 가이드라인까지 한 번에 확인하세요.


정규식 비밀번호 검증 패턴 총정리 - 실무에서 바로 쓰는 코드 예제와 보안 기준까지 한번에

회원가입 폼을 만들 때마다 비밀번호 검증 코드를 새로 검색하게 됩니다. 분명 지난 프로젝트에서도 썼는데, 막상 다시 쓰려면 전방탐색 문법이 헷갈리고 검색 결과마다 패턴이 조금씩 다릅니다. 그래서 이번에 정규식 비밀번호 검증 패턴을 조건별로 정리했습니다. 복사해서 바로 쓸 수 있는 패턴 5가지와 함께, 각 패턴이 어떤 원리로 동작하는지까지 설명합니다.

비밀번호 검증, 왜 정규식이 표준일까

비밀번호 조건을 if문으로 하나씩 검사하면 코드가 금방 길어집니다. 길이 확인, 대문자 포함 확인, 숫자 포함 확인, 특수문자 확인까지 각각 반복문이나 조건문을 쓰면 10줄이 넘어갑니다. 정규식을 쓰면 이 모든 조건이 한 줄로 끝납니다.

또 하나의 장점은 언어를 가리지 않는다는 점입니다. 자바스크립트, 파이썬, 자바, PHP 어디서든 거의 같은 패턴이 동작합니다. 프론트엔드에서 쓴 패턴을 백엔드 검증에 그대로 재사용할 수 있다는 뜻입니다.

핵심 문법: 전방탐색(Lookahead) 이해하기

비밀번호 검증 정규식의 핵심은 (?=...) 문법, 즉 전방탐색입니다. 대표적인 패턴 하나를 분해해 보겠습니다.

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$

  • ^$ : 문자열의 시작과 끝. 전체 문자열을 검사하겠다는 선언입니다.
  • (?=.*[a-z]) : 어딘가에 소문자가 최소 1개 있어야 한다는 조건. 위치를 소비하지 않고 조건만 확인합니다.
  • (?=.*[A-Z]) : 대문자 최소 1개 포함 조건입니다.
  • (?=.*\d) : 숫자 최소 1개 포함 조건입니다.
  • .{8,} : 실제로 매칭되는 부분. 아무 문자나 8자 이상이라는 뜻입니다.

전방탐색은 커서를 움직이지 않고 조건만 검사합니다. 그래서 여러 개를 나란히 붙이면 AND 조건이 됩니다. 이 원리만 이해하면 어떤 조합의 검증 패턴도 직접 만들 수 있습니다.

실무에서 바로 쓰는 검증 패턴 5가지

서비스 정책에 따라 골라 쓸 수 있도록 강도별로 정리했습니다.

조건정규식 패턴
영문 + 숫자, 8자 이상^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$
대문자 + 소문자 + 숫자, 8자 이상^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
영문 + 숫자 + 특수문자, 8~20자^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*()]).{8,20}$
4종 조합 + 허용 문자 제한, 8~20자^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()])[A-Za-z\d!@#$%^&*()]{8,20}$
영문 + 숫자, 공백 금지, 8자 이상^(?=.*[A-Za-z])(?=.*\d)(?!.*\s).{8,}$

다섯 번째 패턴의 (?!.*\s)는 부정형 전방탐색입니다. 공백 문자가 하나라도 있으면 검증에 실패합니다. 붙여넣기 과정에서 딸려 오는 공백 때문에 로그인이 안 되는 문제를 예방할 수 있습니다.

참고: 미국 NIST의 디지털 인증 가이드라인 SP 800-63B는 비밀번호 최소 길이 8자를 요구하되, 복잡한 문자 조합을 강제하는 것보다 충분한 길이 확보와 유출된 비밀번호 목록 대조를 더 권장합니다. 조합 규칙이 지나치게 까다로우면 사용자가 오히려 예측 가능한 패턴으로 회피하기 때문입니다.

자바스크립트와 HTML에 적용하기

자바스크립트에서 검증하기

정규식 객체의 test() 메서드를 쓰면 결과가 true 또는 false로 나옵니다.

const pwRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;

function validatePassword(pw) {
  return pwRegex.test(pw);
}

validatePassword('abcd1234');   // false (대문자 없음)
validatePassword('Abcd1234');   // true

HTML pattern 속성으로 검증하기

input 태그의 pattern 속성을 쓰면 자바스크립트 없이도 폼 제출 시점에 브라우저가 검증해 줍니다. 이때 ^$는 자동으로 적용되므로 생략합니다.

<input type="password" required
  pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}"
  title="대소문자와 숫자를 포함해 8자 이상 입력하세요">

이런 입력 검증 로직은 회원가입 폼에만 쓰이는 것이 아닙니다. 키와 몸무게를 입력받는 BMI 계산기나 번호 범위를 다루는 로또번호 생성기 같은 웹 유틸리티도 내부적으로는 모두 입력값 검증을 거쳐 동작합니다. 형식이 다를 뿐 원리는 같습니다.

흔한 실수와 보안 주의사항

정규식은 비밀번호의 형식을 검증할 뿐, 보안을 보장하지 않습니다. 클라이언트 검증은 사용자 편의 기능이고, 실제 방어선은 언제나 서버입니다.

실무에서 자주 나오는 실수를 정리하면 다음과 같습니다.

  • 프론트엔드 검증만 하는 경우 : 브라우저 검증은 개발자 도구로 쉽게 우회됩니다. 서버에서 반드시 같은 검증을 반복해야 합니다.
  • 특수문자 허용 범위를 너무 좁게 잡는 경우 : [!@#$]처럼 몇 개만 허용하면 사용자가 평소 쓰던 비밀번호를 거부당해 이탈합니다. 정책상 필요한 경우가 아니라면 특수문자 종류는 넓게 허용하는 편이 좋습니다.
  • 최대 길이를 안 두는 경우 : 해싱 알고리즘 bcrypt는 입력을 72바이트까지만 반영합니다. 사용하는 해싱 방식에 맞춰 합리적인 상한을 두는 것이 안전합니다.
팁: 패턴을 적용하기 전에 regex101.com 같은 온라인 테스터에서 통과해야 할 값과 실패해야 할 값을 각각 5개 이상 넣어 확인하세요. 전방탐색은 괄호 하나만 빠져도 조건 전체가 바뀌기 때문에, 배포 전 테스트가 필수입니다.

오늘 바로 적용할 두 가지

첫째, 위 표에서 서비스 정책에 맞는 패턴 하나를 골라 프론트엔드와 서버 양쪽에 동일하게 적용하세요. 둘째, 통과 케이스와 실패 케이스를 섞은 테스트 값 10개로 패턴을 검증한 뒤 배포하세요. 이 두 단계만 지켜도 비밀번호 검증에서 생기는 문제의 대부분을 예방할 수 있습니다.

3일 무료체험큰손탐지기, 지금 바로 시작하세요

설치 없이 웹에서 바로 사용 가능 · PC & 모바일 지원

무료체험 시작
카카오톡 상담