PasswordEncoder(비밀번호 암호화)

한민욱·2024년 6월 10일

저번 주에 프로젝트 시작하면서 만들었던 것들을 풀어내보려고 한다.

우선 PasswordEncoder 쓰는 방법

Gradle로 설명할게요.

dependencies{
	implementation 'org.springframework.boot:spring-boot-starter-security'
}

PasswordEncoder Bean 등록

@Configuration
public class CommonConfig {
    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

설정은 이게 끝.

암호화는

 @Autowired
    PasswordEncoder passwordEncoder; // DI
    
    @Test
    void pwdEnc() {
        String pwd = "kedric123";
        String encodedPwd = passwordEncoder.encode(pwd); //암호화 하는부분
        System.out.println(encodedPwd);
    }

결과

{bcrypt}$2a$10$xO99cg0RupsQY4PNvdPJe.neRL7JSplM8t/NQUgBRGnOM19/FbstS

PasswordEncder를 DI 받아서
passwordEncoder.encode(비밀번호)를 해주면 자연스럽게 암호화된다.

테스트 해보니 계속 값은 바뀜.

기존 비밀번호와 맞는지 확인하는 법은

passwordEncoder.matches(클라이언트로부터 받은 비번, 데이터베이스 비번)

별 거 없었네요! 이제 왜 이런 암호화를 쓰는지 알아보도록 할게요.

우선 암호화는 단방향 암호화와 양방향 암호화가 있다.

간단히 말하자면

단방향(MD5, SHA 등)은 암호화(encoding)는 가능해도 복호화(decoding)는 안되는 것을 말하고,

양방향(AES,RSA,DES 등) 은 암호화 및 복호화가 가능한 것이다.

더 자세한 내용은 검색해서 알아보도록 하자.

두 방식을 놓고 보면

단방향으로 암호화된 경우는 복호화가 불가능하기 때문에 암호를 알아내기 어려울 것처럼 보인다.

하지만 여기서 우리가 Spring 이 제공하는 PasswordEncoder를 쓰는 이유가 나온다.

위 암호화 예시에서 언급했지만

PasswordEncoder 를 이용하여 encode하는 경우 암호화된 결과값이 항상 다르게 나온다.

기존 단방향 암호화의 경우,

암호를 알아내려는 공격자가 rainbow table을 이용하여 rainbow attack을 하는경우, 결국 비밀번호를 알아낼 수 있다.

간단히 말하면

kedric1234를 암호화 하는데, 항상 똑같이 암호화된 string이 asdqwe123이라고 한다면

공격자는 암호를 알수 없지만 반대로 asdqwe123가 kedric1234라는 것은 알 수 있다는 것이다.

이런 데이터 목록들을 rainbow table이라고 한다.

rainbow table이란?

레인보우 테이블(Rainbow Table)은 해시 암호화된 비밀번호를 역으로 찾기 위해 사용되는 데이터 구조입니다. 해시 암호화는 비밀번호를 고정 길이의 문자열로 변환하는 방식으로, 암호화를 통해 보안을 강화합니다. 하지만 해시 값을 역으로 비밀번호로 변환하는 것은 어려운 작업이므로, 이를 빠르게 수행할 수 있도록 도와주는 것이 레인보우 테이블입니다.

일반적으로 가능한 모든 비밀번호와 그에 해당하는 해시 값을 계산해두고 이를 저장해 둔 데이터베이스라네요.

한계점

레인보우 테이블은 강력하지만 몇 가지 한계가 있습니다:

  • 메모리 사용량: 가능한 모든 비밀번호를 미리 계산하고 저장해야 하기 때문에 메모리 사용량이 큽니다.
  • 해시 함수 변경: 해시 함수가 변경되면 레인보우 테이블은 무용지물이 됩니다.
  • 솔팅(Salting): 비밀번호에 임의의 값을 추가(솔트)하면 레인보우 테이블 공격을 어렵게 만듭니다. 솔팅된 비밀번호는 동일한 비밀번호라도 다른 해시 값을 가지기 때문입니다.

그래서 BCryptPasswordEncoder를 사용하여 비밀번호를 해싱하고 솔팅을 자동으로 처리해줍니다.

profile
나날이 성장하고 싶은 백엔드 개발자

0개의 댓글