본문 바로가기
프로젝트/끄적끄적

비밀번호 해시 함수 고민과 선택

by 나무후추통 2022. 9. 25.

그림 1. 법적 기준

비밀번호는 법적으로 '일방향 암호화'를 하도록 정해졌습니다. 즉, 복호화가 불가능하도록 저장해야 합니다.

 

 사용자가 비밀번호를 '1234'로 저장했고, DB에 저장된 정보가 'ad1432@!'이라면 사용자는 'ad1432@!'를 입력하지 않습니다. 그렇다면 '1234'를 'ad1432@!'로 바꾸는 기법이 있을 텐데 이러한 기법을 '해싱'이라고 합니다.

 

이 글은 해싱에 대한 정의와 단방향 해시 함수, 적용한 기법에 대해 조사하고 정리했습니다.

 

1. 해싱이란?

 해시 함수(Hash Function)는 임의의 길이의 데이터를 고정된 길이의 데이터로 맵핑하는 함수를 뜻합니다. 이를 통해 얻은 값은 '해시 코드, 값'이라고 합니다.

 

 여기서 입력 값이 Key가 되고 해쉬 함수를 통해서 나온 '코드'를 통해서 자료를 빠르게 탐색할 수 있는 구조를 '해시 테이블'라고 합니다. 해시 함수를 통한 검색은 매우 빠른 속도를 보장하기 때문에 많은 곳에 응용할 수 있습니다.

 

2. 해시 함수의 응용 : 단방향 암호화

 위 해시 함수의 '임의의 길이의 데이터를 고정된 길이의 데이터로 변환' 특징을 이용해서 비밀번호를 암호화하여 저장할 수 있습니다. 즉, 저장된 비밀번호가 '그 값이 원래 무슨 값인지'를 알아내기 힘들도록 만들면 사용자 정보의 유출을 어느 정도 방지할 수 있습니다.

 

 하지만 '무작위로 대입해서 동일한 값을 찾는다'라면 어떻게 될까요? 해시 함수는 '빠른 검색'을 위해서 탄생했습니다. 즉, 컴퓨팅 성능만 좋다면 무작위 대입으로 사용자 정보(이미 이러한 기법으로 찾은 대량의 테이블 정보를 '레인보우 테이블'이라고 합니다)를 찾을 수가 있습니다. 결국 단방향 해쉬 기법을 암호화에 적용하기 위해서는 또 다른 방법이 필요합니다.

 

3. 단방향 해쉬 함수 보완 

3.1 솔팅 기법

그림 2. 솔팅 기법 (출처 : https://websitesecuritystore.com/blog/what-is-password-salting/)

 마치 요리에 소금 치듯, 기존 해쉬 코드를 생성할 때 임의의 문자열을 추가하여 생성하도록 하는 방법이 솔팅(Salting)이라고 합니다. 해시 코드를 생성에 무작위성을 추가하여 원본 패스워드가 어디부터 어디까지인지를 알아보기 힘들도록 하는 것입니다. 

 

3.2 키 스트레칭

그림 3. 키 스트레칭 기법 (출처 : https://en.bitcoinwiki.org/wiki/Key_derivation_function)

 하지만 CPU 뿐만 아니라 GPU와 병렬 연산 컴퓨팅을 사용한다면 위와 같은 값도 쉽게 알아챌 수가 있습니다. 결국 '연산 속도를 늦추는 방법'으로 정보를 알아내기 힘들게 해야 할 것입니다. 이러한 '해쉬 코드를 다시 해쉬 함수에 넣어서 여러 번 연산하는 방법'을 키 스트레칭이라고 합니다.

 

3.3 Adaptive key derivation function : bcrypt

 Adaptive key derivation function은 위에 있는 솔팅과 키 스트레칭을 반복하여 사용자 정보를 더욱 알기 힘들도록 만든 함수입니다. 다양한 방법들 중 프로젝트에 적용한 기법은 bcrypt입니다. 

 

 Bcrypt는 1999년도에 발표가 되었고 많은 플랫폼에서 사용되는 함수입니다. 이 기법의 특징은 '무작위 대입 시 반복 횟수가 증가하도록' 설계가 된 점입니다. 이를 통해서 후에 컴퓨팅 속도가 증가하더라도 '무작위 대입 공격'을 방지할 수가 있습니다. 또한 OpenBSD와 Spring Security에서 기본으로 제공하는 검증된 함수이기 때문에 이를 채택하게 되었습니다.

 

참고자료