Java_Spring Security

Minki CHO·2023년 1월 16일
0

CodeStates

목록 보기
18/43

DelegatingPasswordEncoder

:Spring Security에서 지원하는 PasswordEncoder 구현 객체를 생성해주는 컴포넌트
:DelegatingPasswordEncoder를 통해 애플리케이션에서 사용할 PasswordEncoder를 결정하고, 결정된 PasswordEncoder로 사용자가 입력한 패스워드를 단방향으로 암호화해줌

DelegatingPasswordEncoder 도입 전 문제점

Spring Security 5.0 이전 버전에서는 평전 텍스트Plain text 패스워드를 그대로 사용하는 NoOpPasswordEncoder가 디폴트 PasswordEncoder로 고정되어 있었으나 아래 문제를 해결하기 위해 DelegatingPasswordEncoder를 도입해서 조금 더 유연한 구조로 PasswordEncoder를 사용할 수 있게 됨

문제1) 패스워드 인코딩 방식을 마이그레이션하기 쉽지 않은 오래된 방식을 사용하고 있는 경우
-패스워드 단방향 암호화에 사용되는 hash 알고리즘은 시간이 지나면서 보다 더 안전한 hash 알고리즘이 지속적으로 고안되고 있기 때문에 항상 고정된 암호화 방식을 사용하는 것은 바람직한 방식이 아님
-보안에 취약한 오래된 암호화 방식을 고수하는 애플리케이션은 해커의 아주 좋은 타겟이 될 수 있음

문제2) 스프링 시큐리티는 프레임워크이기 때문에 하위 호환성을 보장하지 않는 업데이트를 자주 할 수 없음
-오래된 하위 버전의 기술이 언젠가 Deprecated되는 것처럼 보안에 취약한 오래된 방식의 암호화 알고리즘 역시 언제까지 관리 대상이 되지는 않음

DelegatingPasswordEncoder 장점

장점1) DelegatingPasswordEncoder를 사용해 다양한 방식의 암호화 알고리즘을 적용할 수 있음. 사용하고자 하는 암호화 알고리즘을 특별히 지정하지 않는다면 Spring Security에서 권장하는 최신 암호화 알고리즘을 사용하여 패스워드를 암호화할 수 있도록 해줌

장점2) 패스워드 검증에 있어서도 레거시 방식의 암호화 알고리즘으로 암호화된 패스워드의 검증을 지원<노이해중>

장점3) Delegating이라는 표현에서 DelegatingPasswordEncoder의 특징이 잘 드러나도록 나중에 암호화 형식을 변경하고 싶다면 언제든지 암호화 방식을 변경할 수 있음
단, 이 경우 기종에 암호화되어 저장되니 패스워드에 대한 마이그레이션 작업이 진행되어야 함
(Delegate:위임하다 뽑다 선정하다)

DelegatingPasswordEncoder를 이용한 PasswordEncoder 생성

코드는 다음과 같음

// PasswordEncoderFactories로 만들 수 있습니다.

PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();

:PasswordEncoderFactories 클래스를 이용한 PasswordEncoder 인스턴스 생성
:PasswordEncoderFactories.createDelegatingPasswordEncoder();를 통해 DelegatingPasswordEncoder의 객체를 생성하고
내부적으로 DelegatingPasswordEncoder가 다시 적절한 PasswordEncoder 객체 생성<노이해중>

Custom DelegatingPasswordEncoder 생성

:Spring Security에서 지원하는 PasswordEncoderFactories 클래스를 이용하면 기본적으로 Spring Security에서 권장하는 PasswordEncoder를 사용할 수 있지만
필요한 경우, DelegatingPasswordEncoder로 직접 PasswordEncoder를 지정해서 Custom DelegatingPasswordEncoder를 직접 사용할 수 있음

String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());

PasswordEncoder passwordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders);

:Custom DelegatingPasswordEncoder 사용

:Map encoders에 원하는 유형의 PasswordEncoder를 추가해
Delegatingpassword의 생성자로 넘겨주면
디폴트로 지정(idForEncode)한 PasswordEncoder를 사용할 수 있음<노이해중>

암호화된 Password Format

Spring Security 5에서는 패스워드를 암호화할 때 암호화 알고리즘 유형을 prefix로 추가함
암호화된 패스워드의 포맷은 다음과 같음
{id}encoderPassword

아래는 바로 위 코드에서 생성한 Custom DelegatingPasswordEncoder에서 지원하는 단방향 암호화 알고리즘 유형에 따른 암호화된 패스워드 예임
1)BCryptPasswordEncoder로 암호화할 경우
결과물 : {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
PasswordEncoder id = bcrypt
endcoderPassword = 2a$10dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG

2)Pbkdf2PasswordEncoder로 암호화할 경우
결과물 : {pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
PasswordEncoder id = pbkdf2
endcoderPassword = 5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc

3)SCryptPasswordEncoder로 암호화할 경우
결과물 : {scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
PasswordEncoder id = scrypt
endcoderPassword = e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=

4)StandardPasswordEncoder로 암호화할 경우
결과물 : {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
PasswordEncoder id = sha256
endcoderPassword = 97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0

핵심

profile
Developer

0개의 댓글