민감한 정보는 어떻게 저장해야 될까?

고라니·2023년 6월 4일
0
post-custom-banner

안녕하세요.

오늘은 비밀번호같은 민감한 정보를 저장하는 방법에 대해서 얘기해보고자 합니다.

웹 서비스에 회원 기능이 있다면
인증을 위해서 회원의 아이디와 비밀번호를 저장해야 할 겁니다.

그럼 저장하는 방법에 대해서 점진적으로 생각해 봅시다.

DB에 그대로 저장

가장 간단하고 기본적인 방법은,
당연히 DB에 패스워드 원문을 저장하는 방법입니다.

하지만, 보안에 아주 취약해진다는 단점이 있습니다.

SQL 인젝션 공격이나 해킹 등으로 DB에 저장된 정보가 유출이 된다면,
이를 이용해 사용자들을 위조할 수 있기 때문에 심각한 문제가 발생하게 됩니다.

또한, 법적으로도 비밀번호 등을 암호화를 하도록 강제하고 있습니다.

단방향 함수

그러면, DB에 저장된 정보가 유출되어도 해커가 이를 쉽게 이용하지 못하도록 암호화하는 방법을 떠올릴 수 있습니다.

대표적인 암호화 방법으로는

  1. 대칭키 암호화
  2. 비대칭키 암호화
  3. Hash 암호화

가 있습니다.

대칭키 암호화 방식과 비대칭키 암호화 방식은 키가 함께 유출이 된다면 복호화가 될 수 있으므로 부적합합니다.
또한, 비대칭키 암호화 방식은 상대적으로 연산이 복잡하고 시간이 오래 걸린다는 단점이 있습니다.

그러면 남은 선택지는 Hash 암호화입니다.

Hash 암호화 방식은 단방향 함수인 Hash 함수를 이용해 데이터를 복호화하는 방식입니다.
단방향 함수이기 때문에, Hash 값을 통해서 원문을 구하기가 매우 어렵습니다.

하지만 웹 서비스의 회원기능을 개발하는 저희는 패스워드의 원문을 알아낼 필요 없이,
패스워드의 일치 여부만 판단하면 됩니다.

저희 목적에 매우 적합합니다.

그럼, 대표적인 Hash 알고리즘에 대해서 알아보겠습니다.

MD5

Message-Digest Algorithm 5의 약자로,
128비트의 Hash 값을 생성해내는 알고리즘입니다.

데이터의 무결성 확인(Checksum)에 자주 이용됩니다.

보안 취약점이 발견되어 이를 사용하기에 적합하지 않습니다.

SHA256

Secure Hash Algorithm 256의 약자로,
256비트의 Hash 값을 생성해내는 알고리즘입니다.

MD5의 취약점이 발견됨에 따라 보안 목적으로 MD5 대신으로 사용되는 알고리즘입니다.

현재까지 알려진 취약점은 없지만, 취약점이 알려진 SHA-1 알고리즘과 비슷한 방식으로 동작하기 때문에
위험성 문제가 있습니다.

이걸로 충분할까?

여기까지 본다면, SHA256 만으로도 충분히 안전한 암호화 시스템을 구축할 수 있습니다.

사람들은 보통 비밀번호를 기억하기 쉬운 단어와 숫자들을 섞어서 사용하는 습관이 있습니다.

이를 이용한 Rainbow Table Attack이 있습니다.

Rainbow Table이란 미리 변환가능한 모든 Hash 값을 계산해서 저장한 표를 의미합니다.

Rainbow Table이 만들어질 때마다 Hash 함수를 바꿀수도 없습니다.
그러면 어떻게 해야할까요?

SALT를 추가한 단방향 함수

암호화하려는 비밀번호에 "SALT" 값을 추가해서 암호화를 한다면 Rainbow Table Attack을 방지할 수 있습니다.

사용된 SALT값은 암호화된 비밀번호와 함께 저장하면 됩니다.

사용자마다 SALT값이 달라지면 Rainbow Table Attack을 당하기 더 어렵습니다.

이제 진짜 충분할까요?

Adaptive One-way Function (적응형 단방향 함수)

아쉽게도 여전히 Brute Force에 약한 모습을 보입니다.

해시 함수들은 보통 해시 테이블의 O(1) 연산에 이용되기 때문에 계산이 매우 빠릅니다.
1초 안에 억단위 개수의 해시값을 계산할 수 있다고 합니다.

그래서 의도적으로 해시값을 구하는 과정에 자원을 많이 쓰는 적응형 단방향 함수를 쓰는 것이 권장됩니다.

적응형 단방향 함수로 BCrypt, Argon2, SCrypt 등이 있습니다.
이 함수들은 해시 값을 구하기 위해서 얼마나 메모리와 CPU를 사용할지 설정할 수 있는데, 이를 "work factor"라고 부릅니다.

"work factor"를 잘 조정해서 하나의 해시값을 계산하기 위해 1초가 걸리게 한다면,
비로소 Brute Force 공격에 대해서도 안전해집니다.

물론 하나의 비밀번호를 암호화하기 위해서 1초가 걸린다면 이는 웹 서비스의 심각한 성능 문제로 이어질 수 있지만,
비밀번호를 이용하는 장기간 인증 방식과 세션을 이용하는 단기간 인증 방식을 적절히 섞어서 사용한다면 보완이 가능합니다.

마무리

오늘은 DB에 비밀번호와 같이 민감한 정보들을 암호화해서 저장하는 방식들에 대해 간단하게 살펴보았습니다.

연관된 주제로, Spring Security의 Password Encoder를 이어서 보신다면 많은 도움이 될 겁니다.

post-custom-banner

0개의 댓글