왜 Password hashing시 Bcrypt 가 추천되어질까?

Kyle·2020년 12월 9일
22
post-thumbnail
post-custom-banner

암호화의 종류

SHA-2(Secure Hash Algorithm 2)

  • 미국 NSA에서 설계한 암호화 해시 함수.
  • digest size는 224, 256, 384or512 bit로 6개의 해시함수로 구성되어졌음.
  • GPU를 이용한 연산속도가 매우 빠르기 때문에 password 암호화에 권장되지 않음
    • GPU 연산속도가 빠를수록 공격자의 하드웨어를 통한 오프라인 brute force에 더 취약하다.
    • 빠른 해시를 사용하여 암호화를 진행시 공격자는 오프라인 공격으로 초당 수십억개의 해시를 계산할 수 있다.

PBKDF2(Password-Based Key Derivation Function)

pbkdf2_hmac(해시함수(sha256..), password, salt, iteration, DLen)

  • 해시함수의 컨테이너 역할을 한다.
  • 검증된 해시함수만을 사용한다.
  • 해시함수와 salt를 적용 후 해시 함수의 반복횟수를 지정하여 암호화할 수 있다.
  • 가장 많이 사용되는 함수. ISO 표준에 적합하며 NIST에서 승인된 알고리즘이다.
    NIST Special Publication 800-132

Bcrypt


bcrypt.hashpw(password, bcrypt.gensalt())

  • 1999년에 publish된 password-hashing function이다.
  • Blowfish 암호를 기반으로 설계된 암호화 함수이며 현재까지 사용중인 가장 강력한 해시 메커니즘 중 하나이다.
  • 보안에 집착하기로 유명한 OpenBSD에서 사용하고 있다.
  • .NET 및 Java를 포함한 많은 플랫폼,언어에서 사용할 수 있다.
  • 반복횟수를 늘려 연산속도를 늦출 수 있으므로 연산 능력이 증가하더라도 brute-forece 공격에 대비할 수 있다.

Scrypt

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)

  • 2009년에 publish된 key derivation function이다.
  • 오프라인 brute forece 공격에 대해 더 강력하지만, 많은 메모리와 CPU를 사용한다.
  • OpenSSL 1.1 이상을 제공하는 시스템에서만 작동한다.
  • 여러 언어의 라이브러리로 제공된다.
  • 다른 암호기반 KDF에 비해 많은 양의 메모리를 사용하도록 설계되었다.
  • 하드웨어 구현을 하는데 크기와 비용이 훨씬 더 비싸기 때문에, 주어진 자원에서 공격자가 사용할 수 있는 병렬처리의 양이 한정적이다.

왜 Bcrypt가 추천되어질까?

bcrypt가 정답은 아닙니다.
SHA 종류가 무조건 나쁘다고 하는 포스팅은 아닙니다.

그러나 많은 보안관련 글들에서 SHA를 암호해싱에 사용하는 암호화 함수들은 GPU를 이용한 공격에 취약하며(SHA family는 연산속도가 매우빠르기 떄문) 많은 메모리를 필요로 하지 않는 점을 문제로 지적하고있습니다.

SHA가 보안에 결함이 있어서 안전하지 않기 때문이 아니라, SHA는 일반적으로 GPU연산에 유리한 32비트 논리 및 산술 연산만 사용하기 때문에, 공격자가 빠른연산으로 공격할 수 있기 때문입니다.

Bcrypt 설계자들은 이런 문제로 SHA가 아닌 Blowfish를 이용하여 구현하였습니다.

  • Bcrypt 설계자들이 기사에서 언급한 내용

    That means one should make any password function as efficient as possible for the setting in which it will operate. The designers of crypt failed to do this. They based crypt on DES, a particularly inefficient algorithm to implement in software because of many bit transpositions. They discounted hardware attacks, in part because crypt cannot be calculated with stock DES hardware. Unfortunately, Biham later discovered a software technique known as bitslicing that eliminates the cost of bit transpositions in computing many simultaneous DES encryptions. While bitslicing won't help anyone log in faster, it offers a staggering speedup to brute force password searches.

이상적으로 봤을때 limit가 없는 연산 능력을 가진 공격자는 모든 종류의 암호화 알고리즘을 해독 할 수 있겠지만, 이는 어디까지나 이론적인 상황이지 실제로 공격자는 컴퓨터자원을 무제한으로 보유하지 않기 때문에, 공격자의 속도를 늦출 수록 암호화 해독이 어려워집니다.

어떤 암호화 함수(bcrypt, pbkdf2, scrypt, ..)를 쓰던 강력하지만, 충분한 시도 횟수, work-factor가 존재한다고 가정할 때, 방어자는 좀 더 느리게 설계된 암호화 방식에 의존하는 것이 낫다고 생각합니다.

왜 NIST는 Bcrypt가 아닌 PBKDF2를 권장할까?

  • NIST는 PBKDF2 정도면 "보안이 충분" 하다고 판단한 것이지, Bcrypt가 안전하지 않다고 명시한 것은 아닙니다. 또한 NIST는 행정기관으로 FIPS(연방 정보 처리 표준)를 따르며, 여기에 SHA-256/512는 포함되어 있지만 blowfish(bcrypt)는 포함되어있지 않기 때문에 Bcrypt보다 PBKDF2를 선호할것이라고 생각됩니다.

그렇다면 PBKDF2 를 이용해서 여러번 iteration을 돌리면 되는것이 아닌가?

  • 공격자의 공격속도를 늦추기 위해 여러번의 iteration을 할 수 있지만, 이 시점에서 bcrypt를 사용하지 않는 이유에 대해 의문점을 갖게 됩니다. GPU기술이 발달하게 됨에 따라 sha를 사용한 암호화에 더 많은 iteration을 추가하여 bcrypt보다 느린 지점까지 속도를 늦춰야 합니다. OWASP(오픈소스 웹 애플리케이션 보안 프로젝트)Password_Storage_Cheat_Sheet 에서는 특별한 이유가 아니라면 Bcrypt 사용을 권장하고 있으며, PBKDF2의 반복횟수는 10,000회 반복을 권장하고 있으며 높은 보안 환경에서는 최대 100,000의 값이 적절할 것이라고 명시하고있습니다.

요약

  • 기본 해시 함수인 SHA, MD5등을 이용하는 것은 빠른 처리속도로 인하여 보안에 취약하기 때문에 충분히 사용자의 password를 보호할 수 없다. key derivation function를 사용하여 암호화를 진행하자.
  • 해시를 강하게 하기 위해서는 무작위 salt와 함께 반복적인 해싱작업이 필요하다.
  • ISO-27001 보안 규정을 준수해야하는 상황이면 PBKDF2를 사용하자.
  • 일반적으로 규정을 준수해야할 상황이 아니면 구현이 쉽고 비교적 강력한 Bcrypt를 사용하자.
  • 보안 시스템을 구현하는데 많은 비용을 투자할 수 있다면, Scrpyt를 사용하자.

혹시나 잘못된부분있으면 피드백 부탁드립니다 _ _)

profile
깔끔하게 코딩하고싶어요
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 7월 18일

안녕하세요. 보안에 대해 잘 몰라 글을 읽다 궁금한 점이 생겨 댓글 남깁니다. 해싱할 때 GPU 연산이 빠르게 가능할 수록 취약하다는 내용이 전체적으로 이어지는 것 같은데 취약하다는 게 이미 패스워드가 암호화된 채로 노출이 되었고 해커가 브루트포스로 암호화를 해가며 실제 패스워드를 찾는 경우를 예로 들었을 때 취약하다는 건가요?

답글 달기