본문 바로가기
Spring/Java

[Spring] Spring security Bcrypt에 대해서

by Devyne 2025. 8. 11.
반응형

 

현재 사내 인트라넷 API를 계속 개발하고 있다.

직원정보 등록 API를 작성하고 있다.

직원정보를 등록할 때 인트라넷에 로그인할 때 쓰이는 비밀번호(PW)값 또한 저장을 한다.

이 비밀번호를 DB에 저장할 때 ‘보안’ 처리 후 저장을 할려고 한다.

 

그러면 두 가지 방식을 고려할 수 있다.

암호화와 해싱 방식이 있다.

 

우선 이 두 가지에 대해서 알아보자.


암호화(Encryption) vs 해싱(Hashing)

암호화 (Encryption)

  • 암호화는 양방향 프로세스이다. 특정 키(Key)를 사용해 원본 데이터를 아무나 읽을 수 없는 암호문으로 바꾼다. 그리고 나중에 동일한 또는 다른 키를 사용해 다시 원본 데이터로 되돌리는 **‘복호화’**가 가능하다.

해싱 (Hashing)

  • 해싱은 단방향 프로세스이다. 원본 데이터를 고정된 길이의 해시(Hash) 값으로 바꾸지만, 절대로 원본 데이터로 되돌릴 수 없다.

Bcrypt에 대해서

spirng security에서 Bcrypt passwordEncoder를 제공한다.

Bcrypt는 단순히 데이터를 해싱하는 것을 넘어, 비밀번호를 안전하게 지키기 위한 두 가지 특별한 장치를 가지고 있다.

  1. 솔트(Salt)
    • 솔트란? : 해싱 직전에 원본 데이터에 추가하는 ‘랜덤 데이터’를 의미한다.
    • 왜 필요한가? : 만약 솔트가 없다면, "1234" 라는 비밀번호는 항상 동일한 해시 값을 갖게 된다. 해커들은 이런 흔한 비밀번호들의 해시 값을 미리 계산해 둔 ‘레인보우 테이블’을 만들어 놓고, DB에서 탈취한 해시 값과 비교하여 원래 비밀번호를 찾아낼 수 있다.
    • Bcrypt의 솔트 : Bcrypt는 해싱할 때마다 매번 새로운 랜덤 솔트를 자동으로 생성하여 사용한다. 따라서 같은 비밀번호 "1234" 라도 DB에 저장될 때마다 완전히 다른 해시 값을 갖게 된다.

즉, 솔트에 의해서 동일한 비밀번호라도 매번 다른 해시 값이 나온다!

  1. 키 스트레칭 (Key Stretching)
    • Bcrypt 는 의도적으로 해싱 과정을 여러 번 반복시켜 속도를 늦추도록 설계되어있다. 해커가 1초에 수십억 번의 비밀번호를 대입해보는 무차별 대입 공격(Brute-force Attack)을 시도하더라도, Bcrypt의 연산 속도 때문에 공격에 필요한 시간이 기하급수적으로늘어나 매우 비효율적이게 된다.

그래서 로그인은 어떻게 돼?

Bcrypt로 생성된 해시 값은 동일한 비밀번호라도 솔트에 의해서 매번 다른 해시 값을 나오는데, 어떻게 로그인 시 비밀번호가 맞는지 확인할 수 있을까?

Bcrypt로 생성된 해시 값 안에는 사용된 솔트 정보가 함께 포함되어 있다.’

[Bcrypt 로그인 인증 과정]

  1. 사용자 입력: 사용자가 로그인 창에 아이디와 비밀번호("mypassword123")를 입력한다.
  2. DB 조회: 서버는 아이디를 이용해 DB에서 해당 사용자의 정보와 저장된 해시 값($2a$10$N9qo8u...)을 가져온다.
  3. 솔트 추출: 서버(정확히는 PasswordEncoder의 matches() 메서드)는 DB에서 가져온 해시 값에서 솔트 정보($2a$10$N9qo...)를 먼저 추출한다.
  4. 입력값 해싱: 추출한 바로 그 솔트를 사용자가 입력한 비밀번호("mypassword123")에 적용하여 해싱한다.
  5. 결과 비교: 4번에서 생성된 새로운 해시 값과 DB에 원래 저장되어 있던 해시 값이 일치하는지 비교한다.
  6. 인증 완료: 두 값이 완벽히 일치하면, "올바른 비밀번호"로 판단하고 로그인을 성공시킨다.

이처럼 Bcrypt는 매번 다른 결과물을 만들면서도, 저장된 솔트 정보를 활용해 정확하게 비밀번호를 검증할 수 있는 매우 스마트하고 안전한 방식이다.

반응형