PasswordEncoder

사용자 세부정보를 찾은 후에 요청에서 얻은 자격증명과 사용자 세부정보에 자격증명과 비교를 한다.

 

정의

 

encode() 주어진 자격증명을 해시나 암호화를 한다.

amtches() 주어진 자격증명과 암호화나 해시화된 자격증명과 일치하는 확인한다.

upgrageEncoding() 경우 인코딩된 비밀번호를 다시 인코딩해야 하는 경우 true를 반환하도록 재정의한다.

 

 

 

단순한 구현

암호기능 없음

public class PlainTextPasswordEncoder implements PasswordEncoder{

        public String encode(CharSequence rawPassword) {

                return rawPassword.toString();

        }

        public boolean matches(CharSequence rawPassword, String encodedPassword) {

                return Objects.equals(rawPassword, encodedPassword);

        }

}

테스트

 

class SpringSecurity04PasswordApplicationTests {

 

        @Test

        void 단순_암호_인코더_테스트() {

                PlainTextPasswordEncoder encoder = new PlainTextPasswordEncoder();

                String password = "tiger";

                

                assertThat(encoder.matches(password,encoder.encode(password))).isTrue();

        }

}

 

학습 테스트를 위한 구현이지, 실제로는 이미 구현된 클래스를 가져다 쓴다.

암호화 알고리즘 기능은 개발자가 구현할 일도 없다.

 

나머지 테스트

 

SCryptPasswordEncoder 추가로 의존하는 라이브러리가 있다.

 

 

 

 

DelegatingPasswordEncoder

자격증명을 검증할 다양한 알고리즘이 필요한 경우 사용한다.

 

자격증명 앞에 접두로 "{알고리즘}" 붙여 상황에 맞게 알고리즘을 실행한다.

 

예시

{noop}tiger , 인코딩하지 않는다.

{bcrypt}tiger , BCryptPasswordEncoder로 인코딩한다.

 

BCryptPasswordEncoder는 기능 구현을 하지 않고, 모든 책임을 구성 PasswordEncoder 에게 위임한다.

 

사용해보기

직접 생성하지 않고, 스프링 시큐리티가 제공하는 팩터리에서 생성해서 사용할 있다.

 

 

 

 

CustomPassword 추가

만일 커스텀한 PasswordEncoder 있다면, 직접 생성해야 한다.

 

createDelegatingPasswordEncoder() 메서드를 그대로 복사해, 커스텀 구현체를 넣어 사용하면 된다.

 

 

 

 

암호화 생성

암호화 복호화 함수와 생성 기능은 자바 언어에서 기본 제공되지 않는다.

스프링 시큐리티는 이를 위해 자체 솔루션을 제공한다.

 

생성기

문자열 기반, 바이트 기반 가지 인터페이스가 존재한다.

 

 

/복호화

 

 

사용해보기

 

import java.nio.charset.StandardCharsets;

import java.util.Arrays;

import java.util.Objects;

 

import org.springframework.security.crypto.encrypt.BytesEncryptor;

import org.springframework.security.crypto.encrypt.Encryptors;

import org.springframework.security.crypto.encrypt.TextEncryptor;

import org.springframework.security.crypto.keygen.KeyGenerators;

import org.springframework.security.crypto.keygen.StringKeyGenerator;

 

public class Test2 {

        public static void main(String[] args) {

                stringBasedEncrption();

                System.out.println();

                byteBasedEncrption();

        }

 

        private static void stringBasedEncrption() {

                System.out.println("문자열 기반 암호화");

                StringKeyGenerator keyGenerator = KeyGenerators.string();

                

                String password = "tiger";

                String solt = keyGenerator.generateKey();

                

                //암호화 하지 않음

//                TextEncryptor encryptor = Encryptors.noOpText();

                //기본

//                TextEncryptor encryptor = Encryptors.text(password, solt);

                //더 강력

                TextEncryptor encryptor = Encryptors.delux(password, solt);

                

                String plainText = "민감한 데이터";

                //encrypt() 매 실행 마다 값이 다르다. 내부적으로 난수를 사용한다.

                String cypherText1 = encryptor.encrypt(plainText);

                String cypherText2 = encryptor.encrypt(plainText);

                

                System.out.println("plainText = " + plainText);

                System.out.println("cypherText1 = " + cypherText1);

                System.out.println("cypherText2 = " + cypherText2);

                System.out.println(encryptor.decrypt(cypherText1));

                System.out.println(Objects.equals(plainText, encryptor.decrypt(cypherText1)));

        }

        private static void byteBasedEncrption() {

                System.out.println("바이트 기반 암호화");

                StringKeyGenerator keyGenerator = KeyGenerators.string();

                

                String password = "민감한 데이터";

                String solt = keyGenerator.generateKey();

                

                //기본

//                BytesEncryptor encryptor = Encryptors.standard(password, solt);

                //더 강력

                BytesEncryptor encryptor = Encryptors.stronger(password, solt);

                

                byte[] plainByte = password.getBytes(StandardCharsets.UTF_8);

                //encrypt() 매 실행 마다 값이 다르다. 내부적으로 난수를 사용한다.

                byte[] cypherByte1 = encryptor.encrypt(plainByte);

                byte[] cypherByte2 = encryptor.encrypt(plainByte);

                

                System.out.println("plainByte" + Arrays.toString(plainByte));

                System.out.println("cypherByte1 = " + Arrays.toString(cypherByte1));

                System.out.println("cypherByte2 = " + Arrays.toString(cypherByte2));

                System.out.println(new String(encryptor.decrypt(cypherByte1), StandardCharsets.UTF_8));

                System.out.println(Objects.equals(plainByte, encryptor.decrypt(cypherByte1)));

        }

}

 

 

 

 

 

spring-security-04-password.zip
0.15MB

 

+ Recent posts