# PasswordEncoder 활용
- 스프링 시큐리티에서는 기본적으로 PasswordEncoder라는 인터페이스를 제공해준다.
- PasswordEncoder는 아래와 같다.
public interface PasswordEncoder {
String encode(CharSequence rawPassword);
boolean matches(CharSequence rawPassword, String encodedPassword);
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}
- encode 메소드는 주어진 문자열을 변환해 반환하는 역할을 수행한다. 즉, 주어진 암호의 해시를 제공하거나 암호화를 수행하는 일을 한다.
- 인코딩된 문자열이 원시 암호와 일치하는지 나중에 확인하는 데는 matches 메서드를 이용할 수 있다.
- 세 번째 메소드인 upgradeEncoding은 기본값 false를 반환한다. true를 반환하도록 메소드 재정의하면 인코딩된 암호를 보안 향상을 위해 다시 인코딩한다. (모호하기 때문에 개인적으로 좋아하진 않는다.)
# Password 인코더의 다양한 사용법
- NoOpPasswordEncoder - 암호를 인코딩하지 않고 일반 텍스트로 사용하는 설정
- StandardPasswordEncoder - SHA-256을 이용해 암호를 해시한다. (강도가 약한 알고리즘이기 때문에 레거시 시스템에서 사용한다.)
- Pbkdf2PasswordEncoder - PBKDF2를 이용한다. (반복 횟수 인수만큼 HMAC를 수행하는 아주 단순하고 느린 해 함수이다.)
- BCryptPasswordEncoder - bcrypt 강력 해싱 함수로 암호를 인코딩한다.
- SCryptPasswordEncoder - scrypt 해싱 함수로 암호를 인코딩한다.
# Password 인코더를 다양하게 활용하는 경우
- PasswordEncoder의 Configuration을 아래와 같이 설정하면 된다.
@Configuration
public class ProjectConfig {
@Bean
public PasswordEncoder passwordEncoder() {
Map<String, PasswordEncoder> encoders = new HashMap<>() ;
encoders.put("noop", NoOpPasswordEncoder.getInstance()) ;
encoders.put("bcrypt", new BCryptPasswordEncoder()) ;
encoders.put("scrypt", new SCryptPasswordEncoder()) ;
return new DelegatingPasswordEncoder("bcrypt", encoders) ;
}
}
# Spring Security의 키 생성기 활용하기
- 스프링 시큐리티는 아래와 같이 두 가지의 기능을 제공해준다.
- 키 생성기 : 해싱 및 암호화 알고리즘을 위한 키를 생성하는 객체
- 암호기 : 데이터를 암호화 및 복호화하는 객체
- 키 생성기는 Byte와 String으로 나눌 수 있고 생성 방식은 아래와 같다.
/** 단건인 경우 */
BytesKeyGenerator keyGenerator = KeyGenerators.secureRandom() ;
byte[] key = keyGenerator.generateKey() ;
int keyLength = keyGenerator.getKeyLength() ;
/** 공유하는 경우 */
BytesKeyGenerator keyGenerator = KeyGenerators.shared(16) ;
byte[] key1 = keyGenerator.generateKey() ;
byte[] key2 = keyGenerator.generateKey() ;
//key1과 key2의 key값은 일치한다.
StringKeyGenerator keyGenerator = KeyGenerator.string() ;
String salt = keyGenerator.generateKey() ;
- 암호화 방식은 TextEncryptor와 BytesEncryptor를 활용할 수 있다.
# BytesEncryptor 방식
- Bytes 암호화 방식은 표준방식과 더 강력한 Stronger 방식이 있다. (두 방식 모두 AES 256 방식을 활용)
- 표준방식은 GCM(갈루아/카운터 모드)를 사용하고 Stronger는 CBC(암호 블록 체인)을 활용한다
String salt = KeyGenerators.String().generateKey() ;
String password = "secret" ;
String valueToEncrypt = "HELLO" ;
BytesEncryptor e = Encryptors.standard(password, salt) ;
byte[] encrypted = e.encrypt(valueToEncrypt.getBytes()) ;
byte[] decrypted = e.decrypt(encrypted) ;
/**
BytesEncryptor e = Encryptors.stronger(password, salt) ;
*/
# TextEncryptor 방식
- TextEncryptor는 Encryptors.text(), Encryptors .delux(), Encryptors.queryableText()와 같이 세 가지 방식이 있다.
- text와 delux의 경우 같은 입력으로 encrypt() 메서드를 반복 호출해도 다른 출력이 되지만 queryableText의 경우에는 같은 값이 출력된다.