[암호화] BCrypt

김형준 Kim Hyeong Jun·2022년 12월 21일
0
post-thumbnail

프로젝트 진행중
회원가입 시, 비밀번호를 단방향 암호를 통해 DB에 저장하는 과정을 추가해주었다.
자연스럽게 로그인 시에 회원이 입력한 값을 암호화해 DB에 있는 암호화된 값과 비교를 하려했는데,
결과가 나의 예상과는 달랐고, 무엇이 문제인지 고민을 해보았다.

시도

저장된 비밀번호(회원가입 시)와 입력된 비밀번호(로그인 시)를

  1. 문자열 비교도 해보고
  2. 스프링 시큐리티에서 제공하는 matches 함수도 이용해 보았다.

일단 단순 문자열 비교는 BCrytp 암호화된 값에 이용할 수 없다고 한다.

또한, 스프링 시큐리티에서 제공하는 위의 함수의 경우는 사용 법을 제대로 숙지하지 못해 잘 못된 사용으로 내가 원하는 값을 얻을 수 없었다.

문제

일단 내가 제대로 숙지하지도 못해서 아예 잘못된 검사를 해놓고서는 궁금해서 같은 문자열을 인코딩해보았다.

실험코드

결과

분명 같은 값을 인코딩했는데 왜...?

도대체 왜 pw1pw2 는 다른 걸까!!!

해결

BCrypt 해싱 함수란?

BCrytp 는 블로피시(Blowfish) 암호에 기반을 둔 단방향 암호화 해시 함수로 현재까지 사용 중인 가장 강력한 해시 메커니즘 중 하나라고 한다.

BCrytp 는 패스워드를 해싱할 때 내부적으로 랜덤 한 salt 를 생성하기 때문에 같은 문자열에 대해서 매번 다른 해싱 결과를 반환한다고 한다.
(랜덤한 값을 소금치듯이 뿌려준다고 salt 라나...?)

이렇게 제공하는 문자열에 salt 처리를 하기 때문에 인코딩되어 반환되는 결과값이 매번 다른 것이다.

비교는 어떻게해? (matches)

BCrytp 해싱 함수로 인코딩된 값은 일반적인 문자열의 비교에 사용되는 equals 메서드를 사용할 수 없다.

매번 다른 salt 처리가 되어 인코딩되기 때문이다.

띠라서 우리는 matches 라는 메서드를 사용해야 한다.

아래는 PasswordEncoder 클래스 내부의 matches 메서드의 설명을 캡쳐한 사진이다.

설명을 해석해보면 (feat. 파파고)

저장소에서 가져온 인코딩된 암호가 인코딩된 후 제출된 원시 암호와 일치하는지 확인합니다. 암호가 일치하면 true를 반환하고 일치하지 않으면 false를 반환합니다. 저장된 암호 자체는 디코딩되지 않습니다.
매개 변수:
rawPassword – 인코딩 및 일치시킬 원시 암호
encodedPassword – 비교할 스토리지의 encodedPassword
반환:
인코딩 후 원시 암호가 저장소의 인코딩된 암호와 일치하는 경우 true

와 같다.

matches 메서드가 필요로하는 매개 변수는

  1. 인코딩하여 비교할 문자열 (평문)

    평문?
    암호학에서 평문은 암호 알고리즘의 입력 대상으로 예정이 된 암호화되지 않은 정보를 의미한다.

  2. 인코딩되어 있는 암호화된 값

이렇게 두가지 이다.

Reference

profile
I want be a developer🙂

0개의 댓글