모르고 쓰던 Bcrypt 암호화

이세민·2025년 8월 11일
post-thumbnail

혹시 이것을 본적 있나요?
BCryptPasswordEncoder는 spirng security에서 비밀번호를 해싱하기 위해 권장하는 PasswordEncoder 구현체입니다.
처음 사용할때에는 자세히 모르고 지나갔던 BCryptPasswordEncoder의 bcrypt 알고리즘에 대해 알아보겠습니다.

bcrypt

bcrypt는 암호화 해시 함수로, salt와 cost 개념을 도입하여 레인보우 테이블과, 브루트 포스 공격에 대한 내성을 갖추고 있습니다.

문자열 출력은

$[식별자, 버전]$[cost]$[salt base64인코딩 22자][hash base64인코딩 31자]

위와 같이 구성됩니다.

salt

레인보우 테이블

salt 개념을 이해하기 위해서 레인보우 테이블에 대해 알아볼 필요가 있습니다.
처음 해싱에 대한 개념이 생기고 사람들이 비밀번호와 같은 정보를 해싱하여 저장하기 시작하면서, 레인보우 테이블이라는 공격 방식이 생겨났습니다.
레인보우 테이블은 미리 해싱값을 저장한 데이터베이스로, 추가 연산없이 데이터베이스에 미리 저장된 해시값과 대조하는것으로 해시값에 대한 평문을 얻을 수 있습니다.

salt로 해결

salt는 해싱을 하기전 특정한 문자열(salt)을 추가로 삽입하여 해싱을 진행하도록합니다.
해싱 알고리즘이 입력값이 조금만 달라져도 결과가 완전히 달라지는 눈사태 효과 특성을 이용하여, salt를 적용하여 평문을 레인보우 테이블로 예측하기 어렵게 합니다.

bcrypt는 비밀번호 해시 과정에서 랜덤으로 salt를 생성하고, 해시 결과에 함께 포함합니다.

이를 통해서 같은 문자열을 bcrypt로 해싱하더라도, 항상 다른 무작위의 값을 출력하게됩니다.

대신 출력에 salt와 결과를 함께 포함하여 검증을 할때에는 기존의 salt를 읽어와 다시 계산하는 방식으로 검증합니다. 이를 통해 레인보우 테이블 공격 방식을 막을 수 있습니다.

cost

cost는 갈수록 높아지는 컴퓨터의 연산 능력으로 가능해지는 브루트 포싱으로부터 안전해지기 위해 도입한 개념입니다.

브루트 포싱
가능한 모든 경우의 수에 대해 연산하여 평문을 알아내는 방법

bcrypt의 cost는 4~31까지 설정가능하고 실제 연산은 2^cost만큼 실행됩니다.
최대 cost를 기준으로 21억번의 암호화 과정의 반복이 필요합니다.

이러한 cost 개념을 통해 bcrypt가 출시된 1999년부터 컴퓨터의 성능이 수십, 수만배 더 좋아진 오늘날까지도 bcrypt는 보안적으로 권장되는 해싱 알고리즘으로 자리잡고 있습니다.

blowfish

bcrypt는 내부적으로 cost에 따른 각 반복당 사용하는 알고리즘으로 blowfish 알고리즘을 사용합니다.

blowfish는 해싱함수인 bcrypt에서 사용하여 해싱 알고리즘으로 오해하기 쉽지만, 대칭키 암호화 알고리즘입니다.

bcrypt에서는 blowfish를 일부 번형하여 해싱 알고리즘으로 사용합니다.

키 스케줄

blowfish는 키를 여러개의 서브키로 나누어 사용하는데, bcrypt에서는 이러한 키 스케줄을 활용하여 입력한 평문과, salt를 cost에 따라 반복적으로 섞어 blowfish의 key를 생성합니다.

해시값 생성

키 스케줄을 통해 평문과 salt가 섞인 blowfish의 key를 사용하여, 고정 문자열 "OrpheanBeholderScryDoubt"를 cost에 따른 반복수만큼 blowfish로 암호화합니다.

OrpheanBeholderScryDoubt
이러한 고정 문자열이 채택된 비하인드 스토리에 대해 조사해보았지만, 공식적인 내용은 없었습니다.
대신 OpenBSD를 암시적으로 나타낸 192bit 문자열이라는 뇌피셜이 유력하다고합니다.

이 결과 값은 bcrypt의 해시값이 됩니다.

profile
gsm 8기 고등학생

0개의 댓글