상세 컨텐츠

본문 제목

DelegatingPasswordEncoder 란?

Spring Security

by Wanderer Kim 2025. 4. 30. 17:23

본문

반응형
{id}encodedPassword

spring security 를 사용하면서 PasswordEncode.DelegatingPasswordEncoder를 접하게 되서, 해당 클래스에 대해서 정리 하였습니다.

 

비밀번호 인코딩이 중요한 이유

비밀번호는 중요한 정보이기 때무넹 평문(plain text)으로 저장되어서는 안 됩니다. spring security에서는 비밀번호를 PasswordEncoder를 이용해 암호화한 후 데이터베이스에 저장하게 됩니다.

하지만 암호화 알고리즘에 대한 보안성 평가는 시간이 지나면서 달라집니다. 따라서 이전 방식의 hash도 지원하면서 새로운 방식으로 전환할 수 있는 구조가 필요합니다. 이런 요구사항을 만족시키기 위해 DelegatingPasswordEncoder가 도입되었습니다.

 

DelegatingPasswordEncoder란?

DelegatingPasswordEncoder는 여러 개의 PasswordEncoder를 위임 방식으로 관리하는 클래스입니다.

각각의 비밀번호가 어떤 인코딩 방식으로 암호화되었는지 구분할 수 이쎅 하기 위해 prefix를 사용합니다.

 

Password Storage Format

{id}encodedPassword

암호 형색은 위와 같습니다. id는 어떤 PasswordEncoder가 사용되는지를 나타내는 식별자 입니다.

아래는 위의 형식으로 저장되는 비밀번호 예제들을 보여줍니다.

{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0

 

  • bcrypt:  bcrypt 방식으로 암호화된 비밀번호라는 것을 나타내고,  BCryptPasswordEncoder 를 구현체로 사용합니다.
  • noop: 암호화되지 않은 평문 비밀번호를 나타내고, NoOpPasswordEncoder를 사용합니다.
  • pbkdf2: pbkdf2 암호화 방식으로 이용해 암호화된 비밀번호이고, Pbkdf2PasswordEncoder를 사용합니다.
  • scrypt: scrypt 암호화 방식으로 암호화된 비밀번호이고, SCryptPasswordEncoder를 사용합니다.
  • sha256: sha256 방식으로 암호하되었고, StandardPasswordEncoder를 사용합니다.

DelegatingPasswordEncoder 기본 사용법

DelegatingPasswordEncoder의 기본 사용법은 아래 코드를 생성하면 됩니다.

PasswordEncoder passwordEncoder =
    PasswordEncoderFactories.createDelegatingPasswordEncoder();

 

아래 코드는 DelegatingPasswordEncoder를 커스텀하는 방법을 보여줍니다.

String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5());
encoders.put("pbkdf2@SpringSecurity_v5_8", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("scrypt", SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1());
encoders.put("scrypt@SpringSecurity_v5_8", SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("argon2", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2());
encoders.put("argon2@SpringSecurity_v5_8", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("sha256", new StandardPasswordEncoder());

PasswordEncoder passwordEncoder =
    new DelegatingPasswordEncoder(idForEncode, encoders);

 

주의할 점

DelegatingPasswordEncoder는 다양한 암호화 알고리즘을 지원하는 장점이 있지만 한가지 주의할 점이 있습니다.

메모리나 데이터베이스에  저장된 비밀번호 데이터에 prefix가 반드시 포함되어 있어야 제대로 작동합니다.

만약 DelegatingPasswordEncoder를 도입할 예정이라면 비밀번호 데이터에 prefix가 포함되어 있는지 확인하고 만약 없다면 마이그레이션으 진행해야 합니다.

728x90

관련글 더보기

댓글 영역