BCrypt 해시 버전 불일치

NTbell·2024년 12월 31일

😺 : 필자경우 data.sql 를 사용해서 DB에 테스트용 데이터를 넣어 api를 테스트 하곤한다
보통 사용자 데이터를 입력할때 예를 들어 (이름, 아이디, 비밀번호) 저장하는데 비밀번호경우 노출이 되면 안되기 때문에 암호화를 해서 저장을 한다

보통 Bcrypt 해시 알고리즘을 통해 암호화하는데 여기서 불일치 문제가 생길 수있다
필자 경우 테스트용이기 때문에 데이터값을 사이트를 통해 암호화 해서 넣음.


🛠️ 비밀번호 해시 버전 불일치란?

  • 웹사이트나 애플리케이션에서 비밀번호를 저장할 때는 해시(암호화) 과정을 거침
  • 대부분 BCrypt라는 해시 알고리즘을 사용해 비밀번호를 안전하게 저장함
  • 하지만 사이트마다 사용하는 BCrypt 버전이 다를 수 있음
  • 이로 인해 비밀번호 검증 과정에서 오류가 발생할 수 있음

🔍 왜 버전이 다를까?

  • BCrypt는 버전마다 해시 값의 포맷이 다름.
  • 예를 들어, Spring Security에서는 기본적으로 $2a$ 버전을 사용하지만, 일부 사이트는 $2y$ 버전을 사용하기도 함

🔑 $2a$$2y$의 차이

  1. $2a$:

    • Spring Security와 대부분의 Java 애플리케이션에서 기본적으로 사용되는 BCrypt 버전임
    • 오래된 버전이지만 여전히 많이 사용됨!
  2. $2y$:

    • PHP와 일부 웹사이트에서 사용되는 BCrypt 버전임
    • $2a$와 거의 동일하지만, 특정 보안 패치가 적용되어 있음
  3. 호환성 문제:

    • $2y$로 해시된 비밀번호는 Spring Security의 BCryptPasswordEncoder에서 검증 시 실패할 가능성이 있음
    • $2a$$2y$로 된 해시를 제대로 처리하지 못할 수 있음

📋 예시

  • PHP에서 해시된 비밀번호: $2y$10$7.e8hsmZP/7vA3/hH5mLJeCfMBD7BXL8LQF69Ivdr4kXl.8h8gGZl.
  • Spring Security에서 사용 중인 BCryptPasswordEncoder:
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    boolean matches = encoder.matches("userPassword", "$2y$10$7.e8hsmZP/7vA3/hH5mLJeCfMBD7BXL8LQF69Ivdr4kXl.8h8gGZl.");
    • 위 코드는 false를 반환할 가능성이 높음
    • 이유는 Spring이 $2y$ 포맷을 제대로 인식하지 못하기 때문임

✅ 해결 방법

  1. 커스텀 BCryptPasswordEncoder 사용

    • $2y$$2a$로 바꿔 처리하는 방식임
    public class CustomBCryptPasswordEncoder extends BCryptPasswordEncoder {
        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
            if (encodedPassword != null && encodedPassword.startsWith("$2y$")) {
                encodedPassword = "$2a$" + encodedPassword.substring(4);
            }
            return super.matches(rawPassword, encodedPassword);
        }
    }
    • 이 방식으로 $2y$ 비밀번호도 $2a$로 인식되도록 처리 가능함
  2. 2a를 암호화하는 사이트를 이용 , 필자경우 테스트용으로 이게 간편해서 사용함
    https://www.browserling.com/tools/bcrypt

profile
어떤 개발자가 되고싶나

0개의 댓글