봄날은 갔다. 이제 그 정신으로 공부하자

패스워드 암호화에 적합한 해시 함수들 본문

보안

패스워드 암호화에 적합한 해시 함수들

길재의 그 정신으로 공부하자 2021. 12. 29. 11:11

이번 글은 지난 글의 후속 글로 패스워드 암호화에 적합한 해시 함수들에 대해 설명합니다.

 

지난 글에서 결론은 Bcrypt 해시 함수 알고리즘이 패스워드 암호화에 적합하다고 설명하고 끝냈었는데 패스워드 암호화에 적합한 함수는 그것만 있는 것이 아닙니다.

이번 글에서는 그러한 함수들에 대해 설명하고자 합니다.

 

우선 지난 글에서 설명한 Bcrypt 함수부터 복습해보도록 하겠습니다.

 

Bcrypt

Bcrypt는 Blowfish 암호에 기반을 둔 해시 함수로 1999년 USENIX에서 발표되었으며 Bcrypt 함수는 OpenBSD 및 수세 리눅스 등의 일부 리눅스 배포판을 포함한 기타 시스템용 기본 암호 해시 함수 입니다.

Bcypt 암호화 해시 알고리즘의 큰 특징은 SHA 계열에서 약점으로 지적된 빠른 연산으로 인한 brute force 공격에 대한 대비책으로 Blowfish의 특징 중 하나인 key setup phase 라는 일종의 막대한 전처리 요구(Salting)로 느리게 만들고 반복횟수(Key Stretching)를 변수로 지정가능하게 하여 작업량 (=해싱시간) 을 조절할 수 있게 하였습니다.

Bcrypt는 입력 값으로 72 bytes character를 사용해야 하는 단점이 있습니다.

이후에 설명할 PBKDF2나 scrypt는 이러한 제약이 없습니다.

 

사용법은 다음과 같습니다.

// 패스워드 DIGEST 생성
let password = “AAA” 
let hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt(10))

// 패스워드 확인
let isValidPassword = BCrypt.checkpw(password, hashedPassword)

 

암호화를 위한 BCrypt.hashpw()함수 호출 시 BCrypt.gensalt(10)을 해주는 부분이 있는데 이부분은 랜덤하게 salt를 만들고 반복 횟수를 2의 10승으로 설정하는 부분입니다.

반복 횟수 지정 없이 BCrypt.gensalt()만 해줄수도 있는데 그럴 경우 반복횟수는 기본 값인 10(2의 10승)으로 설정됩니다.

 

PBKDF2

PBKDF2는 Password-Based Key Derivation Function의 약자로 미국 NIST에서 승인받은 사용자 패스워드를 기반으로 키(Key) 유도를 하기 위한 함수입니다. Bcrypt와 유사하게 사용자 패스워드에 해시함수, 솔트(Salt), 반복 횟수 등을 지정하여 패스워드에 대한 다이제스트(Digest)를 생성하는 방식입니다.

PBKDF2는 아주 가볍고 구현하기 쉬우며, SHA와 같이 검증된 해시 함수만을 사용합니다.

 

이러한 PBKDF2 함수는 다음과 같이 5개 파라미터와 결과값(DIGEST)로 구성됩니다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)

각 파라미터에 대한 설명은 다음과 같습니다.

  - PRF: 난수(예: HMAC)

  - Password: 패스워드

  - Salt: 패스워드를 암호화하기 위한 키값.

  - c: 원하는 iteration 반복 수

  - DLen: 원하는 다이제스트 길이

 

오오~~ Bcrypt보다 더 복잡해졌네요. 

Bcrypt와 달리 PBKDF2로 암호화된 패스워드를 복호화 하기 위해서는 DIGEST와 함께 암호화에 사용한 salt 값을 같이 관리해야 합니다.

 

scrypt

scrypt는 PBKDF2와 유사한 adaptive key derivation function으로 Colin Percival이 2012년 9월 17일 설계했습니다. 

scrypt는 DIGEST를 생성할 때 메모리 오버헤드를 갖도록 설계되어, brute force 공격을 시도할 때 병렬화 처리가 매우 어렵게 되어 있습니다. 따라서 PBKDF2보다 안전하다고 평가되며 미래에 bcrypt에 비해 더 경쟁력이 있다고 여겨지지만 그 경우 더욱 많은 메모리를 사용해야 한다는 단점 또한 있습니다. 

scrypt는 보안에 아주 민감한 사용자들을 위한 백업 솔루션을 제공하는 Tarsnap에서도 사용하고 있습니다. 

 

scrypt의 파라미터는 다음과 같은 6개의 파라미터와 결과값(DIGEST)로 구성됩니다.

DIGEST = scrypt(Password, Salt, N, r, p, DLen)

각 파라미터에 대한 설명은 다음과 같습니다.

  - Password: 패스워드

  - Salt: 패스워드를 암호화하기 위한 키값.

  - N: CPU 비용

  - r: 메모리 비용

  - p: 병렬화(parallelization)

  - DLen: 원하는 다이제스트 길이

 

정리

이번 글에서는 지난번 글에 이어 패스워드 암호화에 대해 설명하였습니다.

패스워드 암호화 알고리즘 중 brute force 공격에 강점을 가지는 세 개(Bcrypt, PBKDF2, scrypt)의 해시 함수에 대해 알아보았는데 세 개 모두 brute force 공격에 대한 강점을 가지고 있으므로 회사 상황에 맞게 적절한 암호화 해시 함수를 사용하는 것을 추천드립니다.

저는 개인적으로 관리와 사용이 쉬운 Bcrypt 사용을 추천 드립니다.

Comments