Spring Security - PasswordEncoder (1 / 2)

조갱·2022년 3월 6일
1

Spring Security

목록 보기
2/3

Spring Security와 Attribute Converter (이곳을 클릭) 이슈에 대한 글을 적다가, 글의 내용이 너무 방대해져 포스팅을 나누어서 하려고 한다.

Spring Security 에 대한 전반적인 내용은 (이곳을 클릭)에서 다루고있다.

이번 포스팅은 Spring Security 에서 제공하는 PasswordEncoder Interface 에 대한 포스팅이다.

PasswordEncoder 구현체에 대해 다루며 총 2부에 걸쳐 내용을 다루고자 한다.
1부 : PasswordEncoder에 대한 전반적인 설명, 알고가면 좋은 지식
2부 : PasswordEncoder 구현체에 대한 세부 내용

1. PasswordEncoder

PasswordEncoder는 Spring Security에서 비밀번호를 (단방향) 암호화하여 저장하기 위한 인터페이스이다. org.springframework.security.crypto.password 패키지에 위치하고 있다.

package org.springframework.security.crypto.password;

public interface PasswordEncoder {

    // 평문 -> 암호문 인코딩
	String encode(CharSequence rawPassword);
	
    // 평문 <> 암호문 일치 비교
	boolean matches(CharSequence rawPassword, String encodedPassword);

    // 인코딩 된 암호문을 (더 나은 보안을 위해) 1회 더 인코딩 할지 여부
	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}
}

2. PasswordEncoder 의 구현체

PasswordEncoder를 상속받아 구현한 (진짜) PasswordEncoder를 살펴보자.
목록으로 살펴보면
AbstractPasswordEncoder
Argon2PasswordEncoder
BCryptPasswordEncoder
DelegatingPasswordEncoder
LazyPasswordEncoder (AuthenticationConfiguration 클래스에서 구현)
LazyPasswordEncoder (WebSecurityConfigureAdapter 클래스에서 구현)
LdapShePasswordEncoder
Md4PasswordEncoder
MessageDigestPasswordEncoder
NoOpPasswordEncoder
Pbkdf2PasswordEncoder
SCryptPasswordEncoder
StandardPasswordEncoder
UnmappedIdPasswordEncoder

로, 총 14개의 구현체 중 Deprecated된 5개를 제외하고 9개가 존재한다.
(Deprecated 되지 않더라도, 불안전한 암호화 때문에 공식적으로 지원하지 않는 구현체들도 존재한다. 해당 내용은 2부에서 설명한다.)

3. 알고 가면 좋은 지식

PasswordEncoder는 encode할 때마다 매번 다른 Password가 생성된다. (동일한 비밀번호라고 할 지라도.) 그 이유는, salt에 있다.

3-1. Salt

salt는 단방향 Hashing 함수에 추가적으로 입력되는 랜덤 데이터이다.

먼 옛날, 비밀번호는 DB에 평문으로 저장되었지만, 시간이 지남에 따라 비밀번호를 보호하기 위한 방법이 개발되어왔다. 솔트는 이러한 방법 중 하나이다.

솔트가 없다면, 단방향 암호화일 지라도, 복호화가 가능할 '수'도 있다. 예를 들어, md5는 단방향 암호화라고 널리 알려져 있지만, md5 디코딩 사이트를 통해 해싱 된 md5의 원문을 볼 수 있다. 이는 원문<->암호문이 테이블 형태로 저장된 데이터를 통해 제공된다. 따라서 솔트는 레인보 테이블 (=레인보우 테이블, rainbow table)과 같은 미리 계산된 테이블을 사용하는 공격을 방어한다.

사용자 이름비밀번호
user1password123
user2password123

사용자 이름솔트값해시될 문자열해시된 값 = (비밀번호 + 솔트값)
user1E1F53135E559C253password123E1F53135E559C25372AE25495A7981C40622D49F9A52E4F1565C90F048F59027BD9C8C8900D5C3D8
user284B03D034B409D4Epassword12384B03D034B409D4EB4B6603ABC670967E99C7E7F1389E40CD16E78AD38EB1468EC2AA1E62B8BED3A

Reference :
Spring Security : https://spring.io/projects/spring-security
Spring Security : https://mangkyu.tistory.com/76
Password Encoder : https://docs.spring.io/spring-security/reference/features/authentication/password-storage.html
salt : https://ko.wikipedia.org/wiki/%EC%86%94%ED%8A%B8_(%EC%95%94%ED%98%B8%ED%95%99)

profile
A fast learner.

0개의 댓글