Post

스프링 부트로 배우는 Spring Security-02 비밀번호 관련

인코딩 vs 해싱 vs 암호화

구분정의목적사용되는 경우특징실사용 사례
인코딩 Encoding데이터를 원래 형식에서 다른 형식으로 변환하는 것데이터를 효율적으로 전송하거나 저장하는 것이 목적데이터 압축, 스트리밍가역적, 키나 패스워드 사용 안 함, 보안 목적 아님Base 64, Wav, MP3 등 데이터를 효율적으로 스트리밍하거나 저장하기 위해 사용.
해싱 Hashing데이터를 해시 문자열로 변환하는 것데이터 무결성을 검증하는 것이 목적입니다데이터 무결성 검증비가역적, 원래 데이터로 되돌릴 수 없음, 단방향 프로세스bcrypt, scrypt 등의 알고리즘을 사용해 데이터의 무결성을 확인. 예로 패스워드 저장 시 해시 사용.
암호화 Encryption키나 패스워드를 사용해 데이터를 변환하는 것-데이터 보호가역적, 키나 패스워드 필요, 복호화 가능RSA와 같은 알고리즘을 사용해 데이터 보호 목적으로 암호화된 텍스트 생성 및 복호화.

가역적 : 어떤 과정이나 변환을 거친 후에도 원래의 상태로 되돌릴 수 있는 성질을 말합니다.

패스워드 저장

예전에 많이 사용하던 SHA-256 같은 해싱 알고리즘은 더 이상 안전하지 않습니다.

왜냐하면 시스템이 발전하면서 최신 시스템들은 SHA-256을 이용해 1초도 안 되는 시간에 수십억 개의 해시 계산을 수행할 수 있기 때문이에요.

Spring Security에서 패스워드를 저장할 때 권장되는 방법은 1초를 워크 팩터로 적용해 적응형 단방향 함수를 사용하는 것입니다.

패스워드 저장의 경우, 해싱은 평문 대신 해시된 값(hd23dd23)을 DB에 저장하여 보안을 강화합니다.

평문을 저장하면 누군가 DB에 접근하여 비밀번호를 탈취할 수 있기 때문 입니다.

로그인 시 사용자의 패스워드를 해싱하여 DB에 저장된 해시와 비교함으로써 인증 과정을 수행합니다.

워크 팩터

워크 팩터란, 시스템에서 패스워드를 확인하는 데 걸리는 시간을 의미합니다.

패스워드를 해싱하고 이것을 저장된 값과 비교하는 데 걸리는 시간이죠.

여기에 상당한 양의 작업이 필요하기 때문에 시스템에서 패스워드를 확인하는 데 최소 1초가 소요됩니다.

비밀번호 해싱 알고리즘에서 주의해야할 점

해싱 알고리즘과 패스워드 저장의 맥락에서 ‘신속성’은 흔히 보안과 상충하는 요소로 여겨집니다.

일반적으로 컴퓨터 알고리즘에서 속도는 중요한 요소이지만, 패스워드 저장에서는 다른 관점이 필요합니다.

일반적인 알고리즘에서는 더 빠른 처리 속도가 더 나은 성능을 의미합니다.

하지만, 패스워드 해싱의 경우에는 속도가 너무 빠르면 보안상 문제가 될 수 있습니다.

해싱이 매우 빠르게 이루어지면, 공격자가 브루트 포스(완전 탐색) 공격을 사용하여 다양한 가능성을 빠르게 시도하고 올바른 패스워드를 찾아낼 가능성이 높아집니다.

따라서, 패스워드 해싱에서는 해싱 과정이 일정 정도 시간이 걸리도록 설계하는 것이 중요합니다.

이를 통해 공격자가 브루트 포스 방식으로 패스워드를 추측하는 것을 더 어렵게 만듭니다. 이런 이유로, 패스워드 해싱 알고리즘은 일반적으로 다른 종류의 알고리즘보다 느리게 작동하도록 설계되어 있습니다.

다시 말해, 패스워드 저장의 경우 해싱 속도가 너무 빠르지 않게 하는 것은 보안을 강화하기 위한 중요한 요소입니다.

적응형 단방향 함수

적응형 단방향 함수의 대표적인 예로 bcrypt, scrypt, argon2 등이 있습니다

Spring Security에는 PasswordEncoder라는 인터페이스가 있습니다.

해당 인터페이스의 구현으로 bcrypt, argon2, scrypt 등이 구현 되어있습니다.

가장 권장되는 PasswordEncoder는 BCryptPasswordEncoder입니다.

PasswordEncoder 여담

PasswordEncoder의 구현들은 사실 모두 해싱을 수행합니다.

인코딩이라는 용어는 디코딩해서 실제 텍스트를 다시 구할 수 있을 때 사용합니다.

이름을 잘 못 지은거죠. ㄷㄷ

사용 방법

@Bean 을 만듭니다. 파라미터로 버전과 작업강도를 제공할 수 있습니다. (10이 기본 값)

1
2
3
4
@Bean
public BCryptPasswordEncoder passwordEncoder(){
   return new BCryptPasswordEncoder();
}
This post is licensed under CC BY 4.0 by the author.