Django 패스워드 암호화 방법

hwstar·2025년 1월 31일

Django

목록 보기
2/3
post-thumbnail

암호화 방법에 대해 공부를 해본 후 내가 사용하는 Framework에서는
어떻게 패스워드를 암호화해서 사용하는지 궁금해서 찾아보았다.

password 필드를 가지고 있는 model을 찾아본 결과 AbstractBaseUser에 존재한것을 볼 수 있다.

이 클래스에서 패스워드를 설정하는 매서드를 찾아 들어가 보았다.
1. set_password()
2. make_password()
3. get_hasher()
4. PBKDF2PasswordHasher.encode()

def make_password(password, salt=None, hasher="default"):

github link

Flow

  1. 기본적인 유효성 검사 (password 입력값 존재여부, 타입 체크)
  2. 단방향 암호화 해시함수 설정
  3. Salt 설정 or 생성
  4. return 설정한 해시함수로 password encoding

Salt란?
password와 함께 해시함수에 사용되어 암호화시켜 보안성을 높이는 역할을 하는 무작위성 데이터이다.
(왜 사용되는지는 밑에서..)

def get_hasher(algorithm="default"):

어떤 해시 알고리즘을 사용할지 결정하고 반환하는 매서드이다.
이때 특정 알고리즘을 매개변수로 지정해주면 custom 하게 사용가능한거 같다.

그렇지 않고 "default" 기본으로 사용하면 settings.PASSWORD_HASHERS 에 있는 알고리즘 중 첫번째것을 사용하도록 되어있다.

django에서는 기본적으로 보안성이 높다고 평가되는 pbkdf2 알고리즘을 사용하고 있다.
settings.PASSWORD_HASHERS

pbkdf2의 full name은 Password-Based Key Derivation Function 2 이다.
비밀번호를 안전하게 저장하기 위해 설계된 키 파생 함수인데 주로 해싱 알고리즘과 함께 사용된다고 한다.

결론적으로 말하자면 해싱 알고리즘만 사용하여 비밀번호를 암호화해서 저장하는것은 보안상 취약하다.
해싱은 단방향 알고리즘이지만 무차별 대입(brute force)기법으로 해킹하면 언젠가 알 수 있다.
이런 무식한 방법은 단순하지만 막을 방법이 없기 때문에 최대한 해커가 정답을 찾는 시간을 매우 오래걸리게 하는 것이 필요하다.

(password가 영문 대소문자, 숫자 포함해서 만들었다고 치더라도
해커가 이렇게 나올 수 있는 경우의 수를 모두 미리 계산해놓고 비교 연산만 해서 찾는다면??
이러한 방식을 Rainbow Table 이라고 부르는데 인터넷에 이미 계산해놓은 table이 있다고도 한다. )

pbkdf2가 더 안전한 키를 파생시키기 위해 이런 특징을 가지고 있다.

pbkdf2 특징

  • 해시 함수 사용 : SHA-256과 같은 해시 함수 기반으로 작동
  • 반복 계산 : 해시 연산을 매우 많이 반복하여 brute force 공격 시간을 늘린다.
  • salt 사용 : 같은 비밀번호라도 추가 데이터로 인해 다른 해시 값으로 저장되어 Rainbow Table 공격을 방어한다.

class PBKDF2PasswordHasher(BasePasswordHasher)

해당 클래스는 BasePasswordHasher라는 추상 클래스 상속 받고 있다. PBKDF2PasswordHasher
(해당 추상 클래스는 인코딩, 디코딩, 검증 등등 필요한 매서드를 정의해 놓았다.)

(이 클래스에서 PBKDF2 방식은 recommend 라고 Docstring에 작성되어있는데
MD5는 not recommended로 나와있다.. ㅋㅋ)

인코딩은 pbkdf2 , sha-256 해시 함수, 여러 반복횟수와 salt를 매개변수로 받아 실제 DB에 저장할 값을 만들어낸다.

실제로 DB에 저장된 예시를 보여주자면 이런식으로 저장되는데

['pbkdf2_sha256', '870000', 'jVopWKoyuCkbdgyIpCzg...', 'rRMmAfvhUCOP...']

디코딩할 때는 '$'을 기준으로 3번 split하고 첫번째부터 algorithm, iterations, salt, hash 값을 의미한다.

이 정보를 이용해서 검증을 하도록 되어있다.

결론

저번 포스팅의 단방향 암호화 기법중 해싱이 있었다. 이것을 이용해서 패스워드를 저장할때 사용한다
는 점에서 내가 사용중인 django 프레임워크는 어떻게 사용중인지에 대한 궁금증을 풀 수 있었다.
또한 django framework의 내부 구현에 대해 직접 code를 찾아 따라가보면서 django 코드 구조도 엿볼 수 있었고 좀 익숙해지는 느낌이 든다.
사실 django에서 너무 많은 기능을 제공하다보니 실제로 어떻게 작동하는지 보다는 어떻게 사용하는지에 초점을 두고 개발을 했었던거 같기도하다. (이런게 frameworker라는 건가?..)
다음에도 이런 궁금증이 들면 직접 구현된 코드를 뜯어보며 공부해봐야겠다.

0개의 댓글