2026년 1월 04일·4분 읽기

bcrypt vs Argon2: 비밀번호 해싱 설정 선택

bcrypt와 Argon2 비교: 보안 특성, 실제 성능 비용, 최신 웹 백엔드에 안전한 파라미터를 선택하는 방법을 설명합니다.

bcrypt vs Argon2: 비밀번호 해싱 설정 선택

비밀번호 해싱이 해결하는 문제

비밀번호 해싱은 백엔드가 비밀번호 자체를 저장하지 않고도 인증을 처리하게 해줍니다. 사용자가 가입할 때 서버는 비밀번호를 단방향 함수(해시)로 처리해 결과물(해시)을 저장합니다. 로그인할 때는 사용자가 입력한 비밀번호를 다시 해시해 저장된 값과 비교합니다.

해시는 암호화가 아닙니다. 해시에는 역방향이 없기 때문에 복호화할 수 없습니다. 바로 그 단방향성이 비밀번호에 해시를 사용하는 이유입니다.

그렇다면 왜 SHA-256 같은 일반적인 빠른 해시를 사용하지 않을까요? 빠른 것은 공격자가 원하는 것입니다. 데이터베이스가 유출되면 공격자는 한 번에 로그인 시도를 반복하는 대신 해시 목록을 가져가 오프라인에서 가능한 한 빠르게 추측을 돌립니다. GPU를 쓰면 빠른 해시는 엄청난 규모로 테스트될 수 있습니다. 고유한 솔트를 써도 빠른 해시는 여전히 브루트포스하기에 저렴합니다.

현실적인 실패 시나리오는 이렇습니다: 작은 웹앱이 사용자 테이블을 유출합니다. 공격자는 이메일과 비밀번호 해시를 얻습니다. 만약 해시가 빠른 함수로 생성됐다면 평범한 비밀번호와 작은 변형은 빠르게 풀립니다. 그 뒤 공격자는 같은 비밀번호로 다른 사이트에 시도(credential stuffing)하거나 앱 내부의 고권한 기능에 접근할 수 있습니다.

좋은 비밀번호 해시는 추측 비용을 높입니다. 목표는 “깨지지 않는 것”이 아니라 “비용과 시간이 너무 많이 들어 시도할 가치가 없게 만드는 것”입니다.

비밀번호 해싱 설정은 다음을 만족해야 합니다:

  • 단방향(검증만 가능, 역변환 불가)
  • 시도당 느리게 동작
  • 병렬 하드웨어(특히 GPU)에 대해 비싸게 만들기
  • 실제 로그인이 여전히 자연스럽게 느껴질 만큼 충분히 빠르기
  • 시간이 지나도 비용을 올릴 수 있도록 조정 가능

bcrypt와 Argon2 한눈에 보기

bcrypt와 Argon2를 비교할 때, 데이터베이스 유출 후 비밀번호 추측을 얼마나 늦출지 선택하는 것입니다.

bcrypt는 더 오래되었고 널리 지원되는 옵션입니다. CPU 위주로 비용을 들이도록 설계되었고 조정할 수 있는 주요 레버는 비용 인자(cost factor) 하나입니다. 또한 좋은 의미에서 ‘단순함’이 장점입니다: 라이브러리에서 찾기 쉽고 배포하기 쉬우며 예측 가능합니다.

Argon2는 더 새롭고 메모리 하드니스(memory-hardness)를 염두에 두고 설계됐습니다. 각 추측이 CPU뿐 아니라 의미 있는 양의 RAM을 사용하도록 강제할 수 있습니다. 이는 공격자가 GPU나 특수 하드웨어를 이용해 대량의 병렬 추측을 할 때 중요합니다. 메모리는 그런 병렬성에서 확장하기 더 어렵고 비용이 큽니다.

Argon2에는 세 가지 변형이 있습니다:

  • Argon2i: 일부 사이드채널 공격에 대한 저항을 강조
  • Argon2d: GPU 저항성을 강조하되 사이드채널 고려가 더 많음
  • Argon2id: 두 가지를 혼합한 실용적 선택으로 비밀번호 해싱의 일반적 기본값

스택이 Argon2id를 지원하고 메모리를 안전하게 조정할 수 있다면 보통 현대적인 기본값으로 가장 좋습니다. 구형 시스템에서 최대 호환성이 필요하면 bcrypt를 고비용 인자와 함께 사용하는 것도 여전히 괜찮습니다.

중요한 보안 속성

핵심 질문은 간단합니다: 공격자가 비밀번호 DB를 훔쳐갔을 때 대규모로 비밀번호를 추측하는 비용이 얼마나 드는가?

bcrypt에서는 비용(워크 팩터)를 제어합니다. 비용이 높을수록 각 추측에 더 오래 걸립니다. 이는 공격자를 늦추지만 로그인 검증도 느려지므로 사용자가 받아들일 수 있는 수준으로 조정해야 합니다.

Argon2id는 시간 비용에 더해 메모리 하드니스를 추가할 수 있습니다. 각 추측은 CPU 시간과 특정 패턴으로 접근하는 RAM을 필요로 합니다. GPU는 계산 집약 작업에 매우 빠르지만 각 병렬 추측에 상당한 메모리가 필요하면 그 이점이 크게 줄어듭니다.

솔트는 필수입니다. 비밀번호마다 고유하고 무작위인 솔트는:

  • 미리 계산된 테이블이 데이터베이스 전체에서 재사용되는 것을 방지
  • 동일한 비밀번호가 사용자들 사이에서 같은 해시를 만들지 않게 함

솔트는 약한 비밀번호를 강하게 만들지는 못합니다. 데이터베이스 유출 후 공격자가 사용자별로 실제 작업을 하게 만드는 것이 주된 역할입니다.

bcrypt의 장점과 한계

bcrypt는 어디서나 배포하기 쉽기 때문에 여전히 널리 사용됩니다. 호환성이 중요하거나 스택에서 암호화 옵션이 제한적이거나 단일 조정 레버를 원할 때 적합합니다.

가장 큰 ‘주의점’은 72바이트 비밀번호 제한입니다. bcrypt는 비밀번호의 처음 72바이트만 사용하고 나머지는 무시합니다. 긴 암구문이나 패스워드 매니저를 사용하는 경우 이 점이 놀라움을 줄 수 있습니다.

bcrypt를 선택하면 비밀번호 길이 동작을 명확히 하세요. 바이트 단위의 최대 길이를 강제하거나 긴 입력을 일관되게 처리하세요. 중요한 것은 사용자가 생각하는 비밀번호와 실제 처리되는 값이 침묵적으로 잘려 다르지 않게 하는 것입니다.

bcrypt는 또한 메모리 하드 옵션만큼 현대의 병렬 크래킹 하드웨어에 강하지 않습니다. 방어는 여전히 유효하지만 각 추측을 비싸게 만들기 위해 적절한 비용 인자를 선택하는 것에 크게 의존합니다.

신규 시스템을 구축하거나 가치 높은 계정(유료 플랜, 관리자 역할)이 있다면 새 해시는 Argon2id로 마이그레이션하고 기존 bcrypt 해시는 사용자가 로그인할 때까지 계속 허용하는 방식이 일반적이고 위험이 적은 경로입니다.

Argon2의 장점과 트레이드오프

Start your secure backend
시각적 도구로 회원가입, 로그인, 비밀번호 재설정을 포함한 백엔드를 만드세요.
Build Now

Argon2는 비밀번호 해싱을 위해 만들어졌습니다. Argon2id는 많은 팀이 선택하는 변형으로, GPU 저항성과 사이드채널 보호를 균형 있게 제공합니다.

Argon2id는 세 가지 매개변수를 제공합니다:

  • 메모리(m): 해시 수행 중 사용하는 RAM 양
  • 시간/반복(t): 그 메모리를 몇 번 통과하는지(패스 수)
  • 병렬성(p): 몇 개의 레인(lane)을 사용하는지(멀티코어 CPU에 유리)

메모리가 주된 이점입니다. 각 추측이 의미 있는 양의 RAM을 필요로 하면 공격자는 병렬로 시도할 수 있는 수가 줄고 RAM과 대역폭에 대한 비용을 지불해야 합니다.

단점은 운영 측면입니다: 해시당 메모리가 많을수록 서버에서 동시에 처리할 수 있는 로그인 수가 줄어들어 부담이 생깁니다. 메모리를 너무 높게 설정하면 큐잉, 타임아웃, 심지어 OOM(메모리 부족) 오류가 발생할 수 있습니다. 또한 남발 공격(abuse) 대비책을 고려해야 합니다: 많은 동시 로그인 시도가 자원 문제를 일으킬 수 있습니다.

Argon2id를 안전하고 사용 가능하게 유지하려면 성능 기능처럼 튜닝하세요:

  • 프로덕션과 유사한 하드웨어에서 벤치마크하기
  • 동시 해싱 작업을 제한(워커 캡, 큐)하기
  • 로그인 시도에 레이트 리밋과 반복 실패에 대한 잠금 적용하기
  • 설정을 서비스 전반에 걸쳐 일관되게 유지해 약한 엔드포인트가 공격 대상이 되지 않게 하기

실제 웹 백엔드에서의 성능 비용

비밀번호 해싱에서는 “더 빠른 것이 항상 좋다”는 잘못된 목표인 경우가 많습니다. 목표는 공격자에게는 비싼 비용을 들게 하면서 실제 사용자는 빠르게 느끼도록 하는 것입니다.

실용적인 방법은 실제 프로덕션 하드웨어에서 검증당 시간 예산을 정하는 것입니다. 많은 팀이 검증당 100~300ms 정도를 목표로 삼지만, 적절한 수치는 트래픽과 서버에 따라 달라집니다. bcrypt와 Argon2의 차이는 무엇에 비용을 쓰느냐입니다: bcrypt는 주로 CPU 시간이고 Argon2는 메모리도 예약할 수 있습니다.

목표 시간을 정하고 측정하기

대상 해시 시간을 선택하고 프로덕션과 유사한 조건에서 테스트하세요. 회원가입/비밀번호 변경 해싱과 로그인 검증을 모두 측정하되 로그인 경로를 우선시하세요.

가벼운 측정 계획 예시는 다음과 같습니다:

  • 동시 로그인 검증을 1, 10, 50으로 테스트하고 p50, p95 레이턴시 기록
  • 캐시나 CPU 부스트로 인한 노이즈를 줄이기 위해 여러 번 반복
  • 데이터베이스 호출을 따로 측정해 해싱 비용을 정확히 파악
  • 동일한 컨테이너와 CPU 제한으로 테스트

피크가 평균보다 더 중요함

대부분의 시스템은 피크 상황에서 실패합니다. 마케팅 이메일로 사용자들이 로그인 페이지에 몰릴 때 해싱 설정이 시스템의 반응성을 결정합니다.

만약 하나의 검증이 250ms 걸리고 서버가 큐가 생기기 전까지 40개를 병렬 처리할 수 있다면, 500건의 로그인 폭주는 다수 초의 대기시간으로 이어질 수 있습니다. 이런 상황에서는 비용을 조금 낮추고 강력한 레이트 리밋을 적용하는 것이 로그인 엔드포인트를 취약하게 만드는 것보다 실제 보안을 더 향상시킬 수 있습니다.

대화형 로그인 예측성 유지

모든 비밀번호 작업이 같은 긴급성을 가질 필요는 없습니다. 대화형 로그인 비용은 안정적으로 유지하고 무거운 작업은 핵심 경로 밖에서 수행하세요. 일반적인 패턴은 rehash-on-login(성공적 로그인 후 사용자의 해시를 업그레이드)이나 마이그레이션·임포트용 백그라운드 작업입니다.

단계별로 매개변수 선택하기

Keep control of your stack
배포하거나 자체 호스팅할 수 있는 실제 소스 코드를 생성하는 앱을 만드세요.
Generate Code

매개변수 튜닝은 공격자 비용을 올리되 로그인 지연이나 서버 불안정을 초래하지 않게 하는 균형입니다.

  1. 스택에서 잘 지원되는 알고리즘을 선택하세요. Argon2id가 잘 지원된다면 보통 기본 선택입니다. 광범위한 호환성이 필요하면 bcrypt도 괜찮습니다.

  2. 프로덕션과 유사한 하드웨어에서 해시당 목표 시간을 정하세요. 피크 부하 중에도 로그인이 매끄럽게 유지되는 값을 고르세요.

  3. 목표 시간을 맞추도록 조정하세요. bcrypt는 비용 인자를 조정하고 Argon2id는 메모리, 반복, 병렬성을 균형 있게 조정합니다. 메모리는 공격자 경제학을 가장 크게 바꾸는 레버입니다.

  4. 해시와 함께 알고리즘과 설정을 저장하세요. 대부분의 표준 해시 포맷은 이 세부를 포함합니다. 또한 데이터베이스 필드가 충분히 길어 해시가 절단되지 않도록 하세요.

  5. rehash-on-login으로 업그레이드 계획을 세우세요. 사용자가 로그인하면 저장된 해시가 현재 정책보다 약하면 다시 해시해 교체합니다.

실용적인 시작점

측정을 하기 전 기본값이 필요하다면 보수적으로 시작해 타이밍에 따라 조정하세요.

  • bcrypt는 많은 팀이 비용 12 정도에서 시작해 실제 측정에 따라 올립니다.
  • Argon2id는 수십에서 수백 MB 범위의 메모리, 시간 비용 24, 병렬성 12 정도가 흔한 출발점입니다.

이 값들은 규칙이 아니라 출발점입니다. 적절한 설정은 트래픽, 하드웨어, 피크 로그인 폭주에 맞는 값입니다.

비밀번호 저장을 약하게 만드는 흔한 실수

Avoid security shortcuts under pressure
요구사항이 바뀌어도 유지보수가 가능한 프로덕션 수준의 앱을 구축하세요.
Get Started

대부분의 실패는 알고리즘 자체의 문제라기보다 설정의 허점에서 옵니다.

솔트 실수가 큽니다. 각 비밀번호마다 고유한 솔트를 저장하세요. 솔트를 재사용하거나 전체 사용자에 하나의 전역 솔트를 쓰면 공격자가 작업을 재활용하거나 계정들을 비교하기 쉬워집니다.

비용 방치도 문제입니다. 팀들이 낮은 비용으로 배포하고 검토하지 않는 경우가 많습니다. 하드웨어는 좋아지고 공격자는 확장되며 한때 괜찮던 설정이 값싸져 버립니다.

Argon2 과도 튜닝도 흔합니다. 메모리를 극단적으로 높이면 이론적으로는 좋아 보이지만 실제로는 로그인 지연, 요청 백로그, OOM을 유발할 수 있습니다.

비밀번호 길이 처리도 중요합니다. 특히 bcrypt의 72바이트 동작에서 조심하세요. 긴 비밀번호를 허용하면서 조용히 잘라버리면 혼란을 초래하고 보안도 약해집니다.

몇 가지 실용적 습관은 대부분 문제를 예방합니다:

  • 비밀번호마다 고유한 솔트 사용(라이브러리에게 생성 맡기기)
  • 로드 테스트와 정기적인 설정 검토
  • Argon2 메모리는 단일 로그인 벤치가 아니라 피크 트래픽에 맞춰 조정
  • 비밀번호 길이 제한을 명확히 하고 일관되게 처리
  • 로그인 엔드포인트에 동시성 제한과 모니터링 적용

더 안전한 설정을 위한 빠른 체크리스트

배포 시와 인프라 변경 시 옆에 두고 확인하세요:

  • 비밀번호별 고유 솔트, 무작위로 생성해 해시와 함께 저장
  • 피크 트래픽을 견디는 해싱 비용, 프로덕션 유사 환경에서 로드 테스트로 검증
  • 해시와 함께 저장된 파라미터, 오래된 계정도 검증하고 나중에 비용을 올릴 수 있게
  • 온라인 공격 제어, 레이트 리밋과 반복 실패에 대한 짧은 잠금 포함
  • 업그레이드 경로, 보통 rehash-on-login

간단한 건전성 검사: 스테이징에서 성공/실패 섞인 로그인 폭주 테스트를 실행하고 엔드투엔드 레이턴시와 CPU/RAM 사용량을 관찰하세요. 로그인 경로가 버거우면 비용을 조정하고 레이트 리밋을 강화하세요. 솔트 같은 필수 요소를 제거해 문제를 ‘고치지’ 마세요.

현실적인 예: 소규모 웹앱을 위한 튜닝

Plan a clean upgrade path
최소한의 중단으로 시간이 지나면서 비용을 올리기 위한 rehash-on-login 패턴을 사용하세요.
Set Up

몇 천 명 규모의 소규모 SaaS 앱을 상상해 보세요. 대부분 시간대는 안정적이지만 뉴스레터 발송 후나 출근 시간에 짧은 로그인 폭주가 있습니다. 이때 선택은 용량 계획이 됩니다.

오프라인 크래킹 비용을 높이기 위해 Argon2id를 선택했다고 가정합시다. 실제 서버 하드웨어에서 목표 검증 시간을 정하세요(예: 100~250ms). 그런 다음 메모리를 보면서 파라미터를 조정해 목표를 맞추세요. 메모리 설정은 동시에 처리할 수 있는 로그인 수를 제한할 수 있으니 주의하세요.

실용적인 튜닝 루프는 다음과 같습니다:

  • 초반에는 보수적인 반복과 병렬성으로 시작
  • 동시성이 불편해질 때까지 메모리를 늘림
  • 시간 비용(반복 수)으로 검증 시간을 미세 조정
  • 단건 테스트만이 아니라 폭주를 시뮬레이트해 재검증

이미 약한 설정의 오래된 해시가 있다면 계속 검증하면서 조용히 업그레이드하세요. 로그인 성공 시 현재 설정으로 재해시해 저장하면 활성 사용자는 강한 해시로 점진적으로 이동합니다.

배포 후에는 로그인 엔드포인트를 다른 중요한 엔드포인트처럼 모니터링하세요: tail 레이턴시(p95/p99), 폭주 시 CPU와 RAM, 실패한 로그인 급증, 오래된 해시가 교체되는 속도 등을 관찰합니다.

다음 단계: 안전하게 배포하고 계속 개선하세요

정책을 문서화하고 살아있는 설정으로 다루세요. 예: “Argon2id: 메모리 X, 반복 Y, 병렬 Z” 또는 “bcrypt 비용 인자 N”과 선택한 날짜 및 검토 주기(6~12개월)를 기록하세요.

업그레이드 경로를 마련해 오래된 해시에 갇히지 않게 하세요. rehash-on-login은 간단하고 대부분의 시스템에서 잘 작동합니다.

강력한 해시는 중요하지만 온라인 악용 방지를 대체하지는 않습니다. 레이트 리밋, 잠금, 신중한 비밀번호 재설정 흐름도 실무 보안에서 똑같이 중요합니다.

AppMaster 같은 노코드 플랫폼으로 백엔드를 구축한다면, 인증 모듈이 기본적으로 강력한 비밀번호 해싱을 사용하는지, 그리고 해싱 비용이 실제 배포할 인프라와 동일한 환경에서 조정되었는지 확인해 보세요. 초기의 작은 테스트가 "안전하고 원활함"과 "안전하지만 부하에서 쓸 수 없음"의 차이를 만드는 경우가 많습니다.

자주 묻는 질문

What problem does password hashing solve?

비밀번호 해싱은 실제 비밀번호를 저장하지 않고 로그인 여부를 확인할 수 있게 합니다. 저장할 때 비밀번호를 단방향 함수로 변환해 해시를 저장하고, 로그인 시 사용자가 입력한 값을 다시 해시해 비교합니다. 데이터베이스가 유출되더라도 공격자는 비밀번호를 바로 읽을 수 없고 추측 작업을 해야 합니다.

Why not just encrypt passwords instead of hashing them?

암호화는 키가 있으면 복호화가 가능하므로 그 키가 유출되거나 잘못 관리되면 비밀번호가 복원될 수 있습니다. 해싱은 설계상 단방향이어서 저장된 값을 원래 비밀번호로 "복호화"할 수 없습니다.

Why is SHA-256 a bad choice for storing passwords?

SHA-256 같은 빠른 해시는 공격자에게 유리합니다. 공격자는 GPU 등을 이용해 오프라인에서 매우 빠르게 추측을 시도할 수 있기 때문입니다. 비밀번호 해시는 의도적으로 느리게(그리고 가능하면 메모리 집약적으로) 만들어 대규모 추측을 비싸게 만들어야 합니다.

What is a salt, and does it actually make passwords safer?

솔트는 각 비밀번호와 함께 저장되는 고유하고 무작위인 값입니다. 동일한 비밀번호가 다른 사용자에서 같은 해시를 만들지 못하게 하고, 미리 계산된 테이블(precomputed tables)을 재사용하지 못하게 막습니다. 다만 솔트 자체만으로는 약한 비밀번호를 강하게 만들지는 못합니다.

When should I choose Argon2id vs bcrypt?

스택에서 Argon2id를 잘 지원하고 메모리를 안전하게 조정할 수 있다면 Argon2id를 선택하세요. 병렬 크래킹에 더 잘 대응하도록 설계되어 있습니다. 반대로 최대 호환성이 필요하고 조정이 단순한 모델을 원하면 bcrypt를 선택하되 충분히 높은 비용 인자를 설정하세요.

What’s the big gotcha with bcrypt and long passwords?

bcrypt는 72바이트 제한이 있습니다: 비밀번호의 처음 72바이트만 사용되고 나머지는 무시됩니다. 사용자가 긴 암구문이나 패스워드 매니저를 쓸 때 놀라지 않도록 바이트 단위 최대 길이를 명확히 하거나 긴 입력을 일관되게 처리하세요.

Which Argon2id parameter matters most, and why?

Argon2id에서 가장 중요한 매개변수는 메모리입니다. 메모리가 많을수록 공격자가 병렬로 시도할 수 있는 수가 줄어들고 RAM과 대역폭 비용이 커집니다. 그러나 메모리를 지나치게 높이면 서버에서 동시에 처리할 수 있는 로그인 수가 줄어들어 문제가 될 수 있으므로 피크 트래픽을 기준으로 조정해야 합니다.

How slow should password hashing be in a web backend?

실제 배포 환경에서 예측 가능한 검증 시간을 목표로 하세요. 보통 1회 검증에 100–300ms 정도를 목표로 삼고 동시성 부하를 테스트합니다. 적절한 설정은 로그인 폭주 시에도 반응성을 유지하면서 오프라인 추측을 비용 높게 만드는 값입니다.

How do I upgrade hashing settings without forcing everyone to reset passwords?

해시와 함께 알고리즘과 설정을 저장하면 오래된 사용자는 그대로 검증하면서 이후 정책을 올릴 수 있습니다. 일반적인 방법은 rehash-on-login: 로그인에 성공하면 저장된 해시가 현재 정책보다 약하면 새 설정으로 재해시해 교체합니다.

What are the most common mistakes that weaken password storage?

자주 발생하는 실수로는 솔트를 사용하지 않거나 재사용하는 것, 초기 비용을 낮게 두고 검토하지 않는 것, Argon2 메모리를 지나치게 올려 로그인 시 타임아웃이나 OOM을 유발하는 것 등이 있습니다. 또한 bcrypt의 길이 처리 문제와 로그인 엔드포인트 보호(레이트 리밋, 짧은 잠금)도 주의해야 합니다.

쉬운 시작
멋진만들기

무료 요금제로 AppMaster를 사용해 보세요.
준비가 되면 적절한 구독을 선택할 수 있습니다.

시작하다