Spring Security와 Attribute Converter (이곳을 클릭) 이슈에 대한 글을 적다가, 글의 내용이 너무 방대해져 포스팅을 나누어서 하려고 한다.
Spring Security 에 대한 전반적인 내용은 (이곳을 클릭)에서 다루고있다.
이번 포스팅은 Spring Security 에서 제공하는 PasswordEncoder Interface 에 대한 포스팅이다.
PasswordEncoder 구현체에 대해 다루며 총 2부에 걸쳐 내용을 다루고자 한다.
1부 : PasswordEncoder에 대한 전반적인 설명, 알고가면 좋은 지식
2부 : 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;
}
}
PasswordEncoder를 상속받아 구현한 (진짜) PasswordEncoder를 살펴보자.
목록으로 살펴보면
AbstractPasswordEncoder
Argon2PasswordEncoder
BCryptPasswordEncoder
DelegatingPasswordEncoder
LazyPasswordEncoder (AuthenticationConfiguration 클래스에서 구현)
LazyPasswordEncoder (WebSecurityConfigureAdapter 클래스에서 구현)
LdapShePasswordEncoder
Md4PasswordEncoder
MessageDigestPasswordEncoder
NoOpPasswordEncoder
Pbkdf2PasswordEncoder
SCryptPasswordEncoder
StandardPasswordEncoder
UnmappedIdPasswordEncoder
로, 총 14개의 구현체 중 Deprecated된 5개를 제외하고 9개가 존재한다.
(Deprecated 되지 않더라도, 불안전한 암호화 때문에 공식적으로 지원하지 않는 구현체들도 존재한다. 해당 내용은 2부에서 설명한다.)
PasswordEncoder
는 encode할 때마다 매번 다른 Password가 생성된다. (동일한 비밀번호라고 할 지라도.) 그 이유는, salt
에 있다.
salt
는 단방향 Hashing 함수에 추가적으로 입력되는 랜덤 데이터이다.
먼 옛날, 비밀번호는 DB에 평문으로 저장되었지만, 시간이 지남에 따라 비밀번호를 보호하기 위한 방법이 개발되어왔다. 솔트는 이러한 방법 중 하나이다.
솔트가 없다면, 단방향 암호화일 지라도, 복호화가 가능할 '수'도 있다. 예를 들어, md5는 단방향 암호화라고 널리 알려져 있지만, md5 디코딩 사이트를 통해 해싱 된 md5의 원문을 볼 수 있다. 이는 원문<->암호문이 테이블 형태로 저장된 데이터를 통해 제공된다. 따라서 솔트는 레인보 테이블 (=레인보우 테이블, rainbow table)과 같은 미리 계산된 테이블을 사용하는 공격을 방어한다.
사용자 이름 | 비밀번호 |
---|---|
user1 | password123 |
user2 | password123 |
사용자 이름 | 솔트값 | 해시될 문자열 | 해시된 값 = (비밀번호 + 솔트값) |
---|---|---|---|
user1 | E1F53135E559C253 | password123E1F53135E559C253 | 72AE25495A7981C40622D49F9A52E4F1565C90F048F59027BD9C8C8900D5C3D8 |
user2 | 84B03D034B409D4E | password12384B03D034B409D4E | B4B6603ABC670967E99C7E7F1389E40CD16E78AD38EB1468EC2AA1E62B8BED3A |
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)