DB에 단순하게 비밀번호를 저장하면 DB가 털리는 순간 모든 비밀번호가 털리기 때문에 절대로 있는 그대로 저장하면 안된다. 이는 정보통신망법, 개인정보보호법 상으로도 불법이다.
따라서 비밀번호 암호화를 해야 하는데 해시 함수로 암호화 하는 방법을 많이 쓴다.
해시 함수를 거친 비밀번호는 알아볼 수 없는 형태로 암호화 된다.
클라이언트가 로그인할 때 비밀번호를 입력하면 서버에선 그게 맞는 비밀번호인지 확인하는 Key를 갖고 있기 때문에 로그인이 된다.
단 해시 함수만 사용하는 방법은 레인보우 테이블(rainbow table)이라는 문제점 때문에 보완이 필요하다. 레인보우 테이블이란 해시함수가 만들수있는 값들을 미리 저장해놓은 것이다.
해커가 DB에서 암호화된 비밀번호들을 확보하고 그에 대한 레인보우 테이블을 가지고 있다면 암호문을 해독할 수 있다.
이를 보완하기 위해서 salting이라는 방법이 있다. 입력받은 평문에 salt라는 랜덤한 문자열을 끼워넣은 상태로 해시 함수를 돌리는 것이다. ASCII에 포함되지 않는 특이한 문자를 써서 salt를 만들기도 한다.
파이썬에서 인코딩을 하면 자료형을 bytes로 바꿔준다. 디코딩은 반대로 bytes를 지정한 형식(UTF-8, ASCII 등)의 str으로 바꿔준다.
입력받은 비밀번호 값을 bcrypt.haspw로 암호화하려면 일단 비밀번호를 인코딩 해줘야 한다. 그리고 암호화에 필요한 salt 또한 생성해준다.
암호화된 비밀번호는 bytes형식인데 이를 바로 DB에 저장해도 str으로 저장하기때문에 앞에 쓸데없는 b'가 붙는다. 그러므로 암호화된 비밀번호를 UTF-8로 디코딩해준다음 저장한다.
import bcrypt
...
hashed_password = bcrypt.hashpw(input_password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
...
User.objects.create(
name = input_name,
email = input_email,
password = hashed_password,
mobile_number = input_mobile,
date_of_birth = input_birthdate,
)