Django에서 User Password 변경할 때

user.set_password(password)
user.save()

django에서 user password를 set할 때 django.contrib.auth에서 제공되는 set_password Method 를 사용하여 비밀번호를 설정한다.

그리고 이렇게 설정된 user의 비밀번호는

장고의 default 암호화 알고리즘에 의해 암호화되어 저장된 것을 확인할 수 있다.

나는 장고의 비밀번호 암호화 알고리즘은 무엇인지, 그리고 다른 암호화 알고리즘에는 또 무엇이 있는지 궁금해졌고 이를 찾아보았다.

비밀번호 암호화 알고리즘

보통 비밀번호를 저장할 때 단순 텍스트 자체로 이를 저장하지 않는다.(이는 범죄나 다름없다고 함!)

‘단방향 해시 함수의 다이제스트(digest)’로 이를 저장하는데, 이는 수학적인 연산을 통해 원본 비밀번호를 변환하여 암호화된 메시지인 digest를 생성하는 것이다.

암호화된 비밀번호로 원본 비밀번호를 구할 수 없기 때문에 단방향이다.

단방향 해시함수 보완하기

단방향 해시 함수만으로는 완전하지 않다.

인식 가능성과 속도에서 문제가 발생한다.

인식가능성

  • 동일한 메시지가 언제나 동일한 digest를 가진다면 공격자는 digest를 최대한 많이 확보한다음 이를 탈취하고 비교하여 원본 메시지를 찾아낼 수 있다. 이와같은 공격방식을 rainbow attack라고 한다.

속도

  • 해시 함수는 암호학에서 널리 사용되지만 원래는 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.
  • 따라서 해시함수의 빠른 처리 속도로 인해 공격자는 매우 빠른 속도로 임의의 문자열의 digest와 해킹할 대상의 digest를 비교할 수 있다.

따라서 단방향 해시 함수를 보완하기 위한 방법들이 필요하다.

솔팅(salting)

솔트는 단방향 해시 함수에서 digest를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다.

그리고 이 원본 메시지에 문자열을 추가하여 digest를 생성하는 것이 salting이다.

키 스트레칭(key stretching)

digest를 여러번의 알고리즘을 돌려 생성하는 방법이다.

brute-force attack에 대비하기 위함이다.

안전한 패스워드 저장

How Django stores passwords?

Django에서는 PBKDF2 알고리즘을 default 암호화 알고리즘으로 사용한다고 한다.

PBKDF2(Password-Based Key Derivation Function)은 다음과 같은 5개의 파라미터로 구성된다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)
  • PRF: 난수(예: HMAC)
  • Password: 패스워드
  • Salt: 암호학 솔트
  • c: 원하는 iteration 반복 수
  • DLen: 원하는 다이제스트 길이

가볍고, 구현하기 쉬우며 NIST(미국표준기술연구소)에 의해 승인된 알고리즘!

Django

공식 문서를 보면 다른 암호화 알고리즘도 적용할 수 있다고 나온다.

bcrypt라는 알고리즘을 예로 들고 있는데, 이를 알아보겠다.(찾아보니 가장 유명한 암호화 알고리즘 인듯 하다)

bcrypt

bcrypt는 애초부터 패스워드 저장을 목적으로 설계되었다. 현재까지 가장 강력한 해시 메커니즘 중 하나라고!

bcrypt로 마찬가지로 단방향 해쉬 알고리즘이다.

비밀번호 변경 시 같은 비밀번호를 사용하지 못하게 하려면?

위에서 살펴봤듯이 대부분의 암호화 알고리즘은 단방향이다.

즉, 암호화된 비밀번호를 복호화하여 원본 비밀번호를 구할 수 없다는 것이다.

하지만 프로젝트 도중 이런 일이 발생했다.

기획 측에서 비밀번호를 변경할 때 그 전에 사용했던 비밀번호를 사용할 수 없게 해달라고 요청한 것!

이런 경우? 복호화 과정 없이 간단하게 구현할 수 있다.

def password_change(self, code: str, password: str):
    user_selector = UserSelector
    user = user_selector.get_user_from_code(code)

    user_selector.check_password_exists(user.email, password)

    user.set_password(password)
    self.user_code_reset(user)
from django.contrib.auth import authenticate

@staticmethod
def check_password_exists(email: str, password: str):
    if(authenticate(email=email, password=password) != None):
       raise Http404

authenticate라는 django.contrib.auth에 정의되어있는 함수를 사용해 인증을 진행한다.

만일 return 되는 user object가 있다면 그 비밀번호는 그 유저가 전에 사용하고 있던 비밀번호 → 변경 불가로 설정

만일 return 되는 user object가 없다면 그 비밀번호는 변경 가능한 비밀번호 → set_password로 변경

Django에서 User Password 변경할 때

user.set_password(password)
user.save()

django에서 user password를 set할 때 django.contrib.auth에서 제공되는 set_password Method 를 사용하여 비밀번호를 설정한다.

그리고 이렇게 설정된 user의 비밀번호는

장고의 default 암호화 알고리즘에 의해 암호화되어 저장된 것을 확인할 수 있다.

나는 장고의 비밀번호 암호화 알고리즘은 무엇인지, 그리고 다른 암호화 알고리즘에는 또 무엇이 있는지 궁금해졌고 이를 찾아보았다.

비밀번호 암호화 알고리즘

보통 비밀번호를 저장할 때 단순 텍스트 자체로 이를 저장하지 않는다.(이는 범죄나 다름없다고 함!)

‘단방향 해시 함수의 다이제스트(digest)’로 이를 저장하는데, 이는 수학적인 연산을 통해 원본 비밀번호를 변환하여 암호화된 메시지인 digest를 생성하는 것이다.

암호화된 비밀번호로 원본 비밀번호를 구할 수 없기 때문에 단방향이다.

단방향 해시함수 보완하기

단방향 해시 함수만으로는 완전하지 않다.

인식 가능성과 속도에서 문제가 발생한다.

인식가능성

  • 동일한 메시지가 언제나 동일한 digest를 가진다면 공격자는 digest를 최대한 많이 확보한다음 이를 탈취하고 비교하여 원본 메시지를 찾아낼 수 있다. 이와같은 공격방식을 rainbow attack라고 한다.

속도

  • 해시 함수는 암호학에서 널리 사용되지만 원래는 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.
  • 따라서 해시함수의 빠른 처리 속도로 인해 공격자는 매우 빠른 속도로 임의의 문자열의 digest와 해킹할 대상의 digest를 비교할 수 있다.

따라서 단방향 해시 함수를 보완하기 위한 방법들이 필요하다.

솔팅(salting)

솔트는 단방향 해시 함수에서 digest를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다.

그리고 이 원본 메시지에 문자열을 추가하여 digest를 생성하는 것이 salting이다.

키 스트레칭(key stretching)

digest를 여러번의 알고리즘을 돌려 생성하는 방법이다.

brute-force attack에 대비하기 위함이다.

안전한 패스워드 저장

How Django stores passwords?

Django에서는 PBKDF2 알고리즘을 default 암호화 알고리즘으로 사용한다고 한다.

PBKDF2(Password-Based Key Derivation Function)은 다음과 같은 5개의 파라미터로 구성된다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)
  • PRF: 난수(예: HMAC)
  • Password: 패스워드
  • Salt: 암호학 솔트
  • c: 원하는 iteration 반복 수
  • DLen: 원하는 다이제스트 길이

가볍고, 구현하기 쉬우며 NIST(미국표준기술연구소)에 의해 승인된 알고리즘!

Django

공식 문서를 보면 다른 암호화 알고리즘도 적용할 수 있다고 나온다.

bcrypt라는 알고리즘을 예로 들고 있는데, 이를 알아보겠다.(찾아보니 가장 유명한 암호화 알고리즘 인듯 하다)

bcrypt

bcrypt는 애초부터 패스워드 저장을 목적으로 설계되었다. 현재까지 가장 강력한 해시 메커니즘 중 하나라고!

bcrypt로 마찬가지로 단방향 해쉬 알고리즘이다.

비밀번호 변경 시 같은 비밀번호를 사용하지 못하게 하려면?

위에서 살펴봤듯이 대부분의 암호화 알고리즘은 단방향이다.

즉, 암호화된 비밀번호를 복호화하여 원본 비밀번호를 구할 수 없다는 것이다.

하지만 프로젝트 도중 이런 일이 발생했다.

기획 측에서 비밀번호를 변경할 때 그 전에 사용했던 비밀번호를 사용할 수 없게 해달라고 요청한 것!

이런 경우? 복호화 과정 없이 간단하게 구현할 수 있다.

def password_change(self, code: str, password: str):
    user_selector = UserSelector
    user = user_selector.get_user_from_code(code)

    user_selector.check_password_exists(user.email, password)

    user.set_password(password)
    self.user_code_reset(user)
from django.contrib.auth import authenticate

@staticmethod
def check_password_exists(email: str, password: str):
    if(authenticate(email=email, password=password) != None):
       raise Http404

authenticate라는 django.contrib.auth에 정의되어있는 함수를 사용해 인증을 진행한다.

만일 return 되는 user object가 있다면 그 비밀번호는 그 유저가 전에 사용하고 있던 비밀번호 → 변경 불가로 설정

만일 return 되는 user object가 없다면 그 비밀번호는 변경 가능한 비밀번호 → set_password로 변경

Django에서 User Password 변경할 때

user.set_password(password)
user.save()

django에서 user password를 set할 때 django.contrib.auth에서 제공되는 set_password Method 를 사용하여 비밀번호를 설정한다.

그리고 이렇게 설정된 user의 비밀번호는

장고의 default 암호화 알고리즘에 의해 암호화되어 저장된 것을 확인할 수 있다.

나는 장고의 비밀번호 암호화 알고리즘은 무엇인지, 그리고 다른 암호화 알고리즘에는 또 무엇이 있는지 궁금해졌고 이를 찾아보았다.

비밀번호 암호화 알고리즘

보통 비밀번호를 저장할 때 단순 텍스트 자체로 이를 저장하지 않는다.(이는 범죄나 다름없다고 함!)

‘단방향 해시 함수의 다이제스트(digest)’로 이를 저장하는데, 이는 수학적인 연산을 통해 원본 비밀번호를 변환하여 암호화된 메시지인 digest를 생성하는 것이다.

암호화된 비밀번호로 원본 비밀번호를 구할 수 없기 때문에 단방향이다.

단방향 해시함수 보완하기

단방향 해시 함수만으로는 완전하지 않다.

인식 가능성과 속도에서 문제가 발생한다.

인식가능성

  • 동일한 메시지가 언제나 동일한 digest를 가진다면 공격자는 digest를 최대한 많이 확보한다음 이를 탈취하고 비교하여 원본 메시지를 찾아낼 수 있다. 이와같은 공격방식을 rainbow attack라고 한다.

속도

  • 해시 함수는 암호학에서 널리 사용되지만 원래는 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.
  • 따라서 해시함수의 빠른 처리 속도로 인해 공격자는 매우 빠른 속도로 임의의 문자열의 digest와 해킹할 대상의 digest를 비교할 수 있다.

따라서 단방향 해시 함수를 보완하기 위한 방법들이 필요하다.

솔팅(salting)

솔트는 단방향 해시 함수에서 digest를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다.

그리고 이 원본 메시지에 문자열을 추가하여 digest를 생성하는 것이 salting이다.

키 스트레칭(key stretching)

digest를 여러번의 알고리즘을 돌려 생성하는 방법이다.

brute-force attack에 대비하기 위함이다.

안전한 패스워드 저장

How Django stores passwords?

Django에서는 PBKDF2 알고리즘을 default 암호화 알고리즘으로 사용한다고 한다.

PBKDF2(Password-Based Key Derivation Function)은 다음과 같은 5개의 파라미터로 구성된다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)
  • PRF: 난수(예: HMAC)
  • Password: 패스워드
  • Salt: 암호학 솔트
  • c: 원하는 iteration 반복 수
  • DLen: 원하는 다이제스트 길이

가볍고, 구현하기 쉬우며 NIST(미국표준기술연구소)에 의해 승인된 알고리즘!

Django

공식 문서를 보면 다른 암호화 알고리즘도 적용할 수 있다고 나온다.

bcrypt라는 알고리즘을 예로 들고 있는데, 이를 알아보겠다.(찾아보니 가장 유명한 암호화 알고리즘 인듯 하다)

bcrypt

bcrypt는 애초부터 패스워드 저장을 목적으로 설계되었다. 현재까지 가장 강력한 해시 메커니즘 중 하나라고!

bcrypt로 마찬가지로 단방향 해쉬 알고리즘이다.

비밀번호 변경 시 같은 비밀번호를 사용하지 못하게 하려면?

위에서 살펴봤듯이 대부분의 암호화 알고리즘은 단방향이다.

즉, 암호화된 비밀번호를 복호화하여 원본 비밀번호를 구할 수 없다는 것이다.

하지만 프로젝트 도중 이런 일이 발생했다.

기획 측에서 비밀번호를 변경할 때 그 전에 사용했던 비밀번호를 사용할 수 없게 해달라고 요청한 것!

이런 경우? 복호화 과정 없이 간단하게 구현할 수 있다.

def password_change(self, code: str, password: str):
    user_selector = UserSelector
    user = user_selector.get_user_from_code(code)

    user_selector.check_password_exists(user.email, password)

    user.set_password(password)
    self.user_code_reset(user)
from django.contrib.auth import authenticate

@staticmethod
def check_password_exists(email: str, password: str):
    if(authenticate(email=email, password=password) != None):
       raise Http404

authenticate라는 django.contrib.auth에 정의되어있는 함수를 사용해 인증을 진행한다.

만일 return 되는 user object가 있다면 그 비밀번호는 그 유저가 전에 사용하고 있던 비밀번호 → 변경 불가로 설정

만일 return 되는 user object가 없다면 그 비밀번호는 변경 가능한 비밀번호 → set_password로 변경

Django에서 User Password 변경할 때

user.set_password(password)
user.save()

django에서 user password를 set할 때 django.contrib.auth에서 제공되는 set_password Method 를 사용하여 비밀번호를 설정한다.

그리고 이렇게 설정된 user의 비밀번호는

장고의 default 암호화 알고리즘에 의해 암호화되어 저장된 것을 확인할 수 있다.

나는 장고의 비밀번호 암호화 알고리즘은 무엇인지, 그리고 다른 암호화 알고리즘에는 또 무엇이 있는지 궁금해졌고 이를 찾아보았다.

비밀번호 암호화 알고리즘

보통 비밀번호를 저장할 때 단순 텍스트 자체로 이를 저장하지 않는다.(이는 범죄나 다름없다고 함!)

‘단방향 해시 함수의 다이제스트(digest)’로 이를 저장하는데, 이는 수학적인 연산을 통해 원본 비밀번호를 변환하여 암호화된 메시지인 digest를 생성하는 것이다.

암호화된 비밀번호로 원본 비밀번호를 구할 수 없기 때문에 단방향이다.

단방향 해시함수 보완하기

단방향 해시 함수만으로는 완전하지 않다.

인식 가능성과 속도에서 문제가 발생한다.

인식가능성

  • 동일한 메시지가 언제나 동일한 digest를 가진다면 공격자는 digest를 최대한 많이 확보한다음 이를 탈취하고 비교하여 원본 메시지를 찾아낼 수 있다. 이와같은 공격방식을 rainbow attack라고 한다.

속도

  • 해시 함수는 암호학에서 널리 사용되지만 원래는 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.
  • 따라서 해시함수의 빠른 처리 속도로 인해 공격자는 매우 빠른 속도로 임의의 문자열의 digest와 해킹할 대상의 digest를 비교할 수 있다.

따라서 단방향 해시 함수를 보완하기 위한 방법들이 필요하다.

 

솔팅(salting)

솔트는 단방향 해시 함수에서 digest를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다.

그리고 이 원본 메시지에 문자열을 추가하여 digest를 생성하는 것이 salting이다.

키 스트레칭(key stretching)

digest를 여러번의 알고리즘을 돌려 생성하는 방법이다.

brute-force attack에 대비하기 위함이다.

 

출처: https://d2.naver.com/helloworld/318732

How Django stores passwords?

Django에서는 PBKDF2 알고리즘을 default 암호화 알고리즘으로 사용한다고 한다.

PBKDF2(Password-Based Key Derivation Function)은 다음과 같은 5개의 파라미터로 구성된다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)
  • PRF: 난수(예: HMAC)
  • Password: 패스워드
  • Salt: 암호학 솔트
  • c: 원하는 iteration 반복 수
  • DLen: 원하는 다이제스트 길이

가볍고, 구현하기 쉬우며 NIST(미국표준기술연구소)에 의해 승인된 알고리즘!

https://docs.djangoproject.com/en/4.1/topics/auth/passwords/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

공식 문서를 보면 다른 암호화 알고리즘도 적용할 수 있다고 나온다.

bcrypt라는 알고리즘을 예로 들고 있는데, 이를 알아보겠다.(찾아보니 가장 유명한 암호화 알고리즘 인듯 하다)

bcrypt

bcrypt는 애초부터 패스워드 저장을 목적으로 설계되었다. 현재까지 가장 강력한 해시 메커니즘 중 하나라고!

bcrypt로 마찬가지로 단방향 해쉬 알고리즘이다.

비밀번호 변경 시 같은 비밀번호를 사용하지 못하게 하려면?

위에서 살펴봤듯이 대부분의 암호화 알고리즘은 단방향이다.

즉, 암호화된 비밀번호를 복호화하여 원본 비밀번호를 구할 수 없다는 것이다.

하지만 프로젝트 도중 이런 일이 발생했다.

기획 측에서 비밀번호를 변경할 때 그 전에 사용했던 비밀번호를 사용할 수 없게 해달라고 요청한 것!

이런 경우? 복호화 과정 없이 간단하게 구현할 수 있다.

def password_change(self, code: str, password: str):
    user_selector = UserSelector
    user = user_selector.get_user_from_code(code)

    user_selector.check_password_exists(user.email, password)

    user.set_password(password)
    self.user_code_reset(user)
from django.contrib.auth import authenticate

@staticmethod
def check_password_exists(email: str, password: str):
    if(authenticate(email=email, password=password) != None):
       raise Http404

authenticate라는 django.contrib.auth에 정의되어있는 함수를 사용해 인증을 진행한다.

만일 return 되는 user object가 있다면 그 비밀번호는 그 유저가 전에 사용하고 있던 비밀번호 → 변경 불가로 설정

만일 return 되는 user object가 없다면 그 비밀번호는 변경 가능한 비밀번호 → set_password로 변경

BELATED ARTICLES

more