[보안] 비밀번호 암호화, salt, pepper, key stretching

나른한 개발자·2022년 5월 27일
0

데이터베이스에 정보를 저장할 때 어떤 정보는 암호화해서 저장해야한다. 특히 비밀번호나 바이오 정보같은 개인정보는 반드시 암호화를 하도록 법으로 규정하고 있다.

비밀번호를 암호화할 때에는 주로 다시 복호화할 수 없는 단방향 암호화 알고리즘을 사용하는데, 단방향 알고리즘의 문제점은 같은 문자열에 대해 항상 같은 다이제스트가 나오기 때문에 Rainbow Table Attack에 취약하다는 것이다. 따라서 해시 알고리즘은 암호화보다는 오로지 해싱을 위한 것이라고 생각하면 된다. 이때 salt와 pepper를 사용하면 이러한 취약점을 보완할 수 있다.

Salt

Salt는 랜덤한 값이며 비밀번호와 함께 해싱이 된다. 따라서 사용자가 짧고 간단한 조합의 비밀번호를 사용한다고해도 솔트값에 의해 값을 좀 더 복잡하게 만들 수 있다. 해싱을 한 값과 솔트 값을 모두 데이터베이스에 저장하여 사용자가 비밀번호 입력했을 때 일치 여부를 판단한다. 공격을 위해 미리 계산된 테이블이 필요하기 때문에 해킹 과정이 더 복잡해지고 그 시간을 지연시킬 수 있다.

Pepper

솔팅도 좋은 방법이지만 데이터베이스에 함께 저장이 되기 때문에 이에 데이터베이스에 저장되지 않는 값인 pepper라는 레이어를 한가지 더 할 수 있다. 페퍼 역시 랜덤 값인데, 솔트는 비밀번호마다 값이 다르다면 페퍼는 모든 유저에게 동일한 값이 저장된다.

다만 페퍼는 DB에 저장되지 않기 때문에 하드코딩될 수 있는데, 페퍼가 노출되면 결국엔 솔트와도 별다를 게 없어져 페퍼가 그닥 실용적인 방법이 아니라는 의견도 있다. (설정 파일로 따로 관리하면 괜찮을 것 같기도?)

Key Stretching

Key Stretching은 해시된 값을 또 다시 해시 함수의 입력 값으로 넣어 해싱을 반복하는 것이다. 이렇게 하면 무작위 대입을 통해 해시 값을 구하는 시간을 늘려 레인보우 테이블이나 무차별 대입 공격을 하기에도 더 어려워진다.

일반적인 환경에서 다이제스트를 생성하는데 일정 시간이 (대략 0.2초 정도) 걸리도록 하여 무차별 공격에도 같은 시간에 비교할 수 있는 값의 수를 줄일 수 있다. 컴퓨터 성능이 더 좋아진다면 반복 횟수를 늘려 대응할 수 있다.

이러한 salting과 key stretching 을 구현한 Adaptive Key Derivation Functions가 있는데 이를 사용하면 간편하게 암호화를 할 수 있다. 암호화를 구현할 때 자신이 직접 암호화 로직을 짜는 것보다 Adaptive Key Derivation Functions를 쓰는 것이 문제가 생겼을 때 원인 파악도 쉽고 GPU같은 장비를 사용한 병렬화를 어렵게 만들어 사용이 권장된다.

Adaptive Key Derivation Functions 종류

  • PBKDF2
  • bcrypt
  • scrypt

이정도까지하면 값이 유출되어도 큰 위험은 없다고 한다. 개인적으로는 사용하기 쉬운 bcrypt를 이용하여 salt와 key stretching으로 보안 수준을 유지하는 것이 좋아보인다.



참고
Learning Password Security Jargon: Password Peppering
패스워드 털려서 써보는 패스워드 암호화
안전한 패스워드 저장

profile
Start fast to fail fast

0개의 댓글