보안

[Spring Security] 해시란? Salt란? BCrypt이해하기

곽코딩루카 2025. 5. 12. 01:14
반응형

안녕하세요, 이번 글에서는 실무에서도 많이 사용하는 BCrypt 해시 알고리즘에 대해 정리해보려고 합니다.
단순히 라이브러리만 사용하는 것을 넘어서, 써야 하는지, 어떻게 동작하는지 까지 이해하는 것이 목표입니다.

 

 

비밀번호 저장은 "암호화"아니라 "해시"

많은 분들이 비밀번호를 암호화해서 저장한다고 말하지만, 정확히는 "해시(Hash)" 해야 합니다.

구분해시 (Hash)암호화 (Encryption)
방향성 단방향 (복호화 불가) 양방향 (복호화 가능)
사용 목적 비교용, 위조 방지 데이터 보호
비밀번호 저장에 적합?    아니오
 

암호화키가 유출되면 누구나 복호화할 있기 때문에 비밀번호 저장용으로는 부적절합니다.
따라서 우리는 복호화가 불가능한 단방향 해시 함수사용해야 합니다.

 

 

해시(Hash)란?

입력값(비밀번호 등)고정된 길이의 문자열로 변환하는 함수

 

  • 복호화가 불가능함
  • 같은 입력 → 항상 같은 출력
  • 대표 알고리즘: SHA-256, SHA-1, MD5, BCrypt

하지만 SHA-256, MD5빠르게 계산되기 때문에 Brute-force 공격에 취약합니다.

 

 

 

 

 

그래서 나온 것이 BCrypt

BCryptBlowfish 알고리즘을 기반으로 만든 비밀번호 저장용 해시 함수입니다.
다음과 같은 특징을 가집니다:

특징설명
Salt 내장 매번 다른 salt생성하여 같은 비밀번호도 다른 해시 생성
Cost factor 지원 연산 횟수를 조절해 공격을 어렵게
복호화 불가능 철저한 단방향 해시
결과 문자열에 정보 포함 salt, cost, 해시값을 모두 문자열에 포함
Spring Security 기본값 BCryptPasswordEncoder바로 사용 가능
 

 

 

 Salt란?

Salt해시 전에 붙이는 무작위 문자열입니다.

같은 비밀번호라도 다른 salt사용하면 완전히 다른 해시값이 생성됩니다.

사용자입력값Salt해시결과
userA password123 abc123 XYZ...
userB password123 zxc987 QWE...
 

이렇게 하면 해커가 사전 만들어둔 레인보우 테이블로 역추적하는 것을 방지할 있습니다.

 

 

 


레인보우 테이블이란?

자주 사용되는 비밀번호에 대한 해시값을 미리 계산해서 저장해둔 테이블

 

예:

123456 → e10adc3949ba59abbe56e057f20f883e  
qwer1234 → ab56b4d92b40713acc5af89985d4b786

 

해시만 보고도 어떤 비밀번호인지 알아낼 있음
Salt쓰지 않으면 공격에 매우 취약합니다.

단순화한 레인보 테이블

 

 

그런데 궁금하죠?

"같은 비밀번호라도 매번 해시값이 달라진다며?

그럼 로그인할 어떻게 비교해요?"

여기서부터가 BCrypt핵심 기술입니다.

 

 

 

BCrypt해시 안에 salt포함시킨다!

BCrypt비밀번호를 해싱하면 다음처럼 생긴 문자열이 나옵니다:

 

$2a$10$WqRf8g1D33tX6SPZzAsT0OZADZ5POZNUKj2HNGIrBxkOcLCUo3GcK

 

구간 의미

$2a$ 알고리즘 버전
10$ Cost factor (2¹⁰ = 1024번 반복)
WqRf8g1D33tX6SPZzAsT0O 22자리 salt
나머지 최종 해시값 (salt + 비밀번호 해싱 결과)

 

로그인할 비교는 어떻게 하나? (스프링 JAVA)

passwordEncoder.matches("입력한 비밀번호", "DB에 저장된 해시값");

 

matches() 내부에서는 다음 과정을 수행합니다:

  1. 저장된 해시값에서 salt, cost 정보추출
  2. 입력한 비밀번호 + 추출된 salt → 같은 방식으로 다시 해싱
  3. 새로 계산한 해시값과 기존 해시값이 일치하면 로그인 성공

✔️ 즉, BCrypt비교에 필요한 모든 정보(salt 포함)해시 문자열에 내장해놓습니다.
별도로 salt저장하거나 비교할 필요가 없습니다.

 

정리

질문핵심 요약
비밀번호는 암호화가 아니라 해시해야 하나요? 복호화되면 되니까
해시만 저장해도 괜찮나요? salt쓰면 안전합니다
같은 비밀번호인데 해시값이 매번 다른 이유는? salt무작위로 들어가기 때문입니다
그럼 어떻게 비교하나요? 해시 안에 salt포함되어 있고, 이를 기반으로 재해싱하여 비교합니다
 

 

BCrypt단순히 "라이브러리를 쓰면 되는 기술"아닙니다.
원리까지 이해해야 보안 사고 없이 안전한 서비스를 설계있습니다.
오늘 포스팅이 여러분의 보안 지식에 도움이 되었길 바랍니다!

반응형