내일배움캠프

230516 python 해싱 세션으로 비밀번호 인증

Neda 2023. 5. 16. 20:33

230516

 

해싱

argon2

처음에는 그냥 예전부터 유명했던 bcrypt를 쓸까 생각했다.

하지만 세상이 급변하는 요즘 새로운 대안도 등장하고 있었다.

그중에서 암호 해싱 대회에서 우승했다고 하는 argon2_cffi를 써보기로 했다.

사용법

사용법은 정말 간단했다. 

사용자의 비밀번호 입력값을 request로 받아왔을 때

그냥 문자열을 넘겨주기만 하면 된다.

from argon2 import PasswordHasher

def create_member():
    ...
    ph = PasswordHasher()
    password = request.form['password']
    password_hash = ph.hash(str(password))
    ...

 

아래와 같은 무작위한 해시 값을 리턴한다.

$argon2id$v=19$m=65536,t=3,p=4$euwlIbAMTyIbVCHYGL0hfw$5OCuVX2Qyfk/V+k+1x6N5ORVKc9cL2jC9SpPSItjugb
  • 1번째 줄(argon2id) : 해시에 사용한 argon2 유형
  • 2번째 줄(v) : argon2의 버전
  • 3번째 줄(m,t,p) : memory cost, time cost, parallelism를 의미한다.  사용자가 직접 정할 수도 있다.
  • 4번째 줄 : 랜덤한 salt값
  • 5번째 줄 : bas64로 인코딩된 hash 값
$argon2id
$v=19
$m=65536,t=3,p=4
$euwlIbAMTyIbVCHYGL0hfw
$5OCuVX2Qyfk/V+k+1x6N5ORVKc9cL2jC9SpPSItjugb

 

해시 비교

비밀번호를 해싱하여 데이터베이스에 저장했다면

사용자가 권한이 필요한 곳에 접근할 때 비밀번호를 입력받아 해시 값을 비교해야 한다

사용자에게 입력받은 'password'와 데이터베이스에 가져온 'member.password'를 

ph.verify()를 통해 비교한다

비교해서 일치한다면 True를 반환하고

일치하지 않는다면 VerifyMismatchError를 반환한다

def validate(name):
    ...
    password = request.form['password']
    member = member_col.find_one({'name':str(name)}, {'_id': False})
    ph.verify(member['password'], str(password))
    ...

 

세션

각 클라이언트마다 고유한 데이터를 서버에서 저장하고

클라이언트에게는 쿠키에 세션키만 저장하여 사용한다.

데이터가 서버에 있기 때문에 클라이언트에서 접근할 수 없어 보안성이 있다.

값을 생성하는 방법은 session에 키와 값을 주면 된다.

세션 생성

세션을 생성하기 전에 flask에 시크릿 키를 설정해주자.

app.secret_key = os.getenv('SECRET_KEY')
session['userName'] = name;

세션에 특정 키가 있는지 확인

if 'userName' in session

세션 키 제거하기

session.pop('userName', None)

세션 비우기

session.clear()

 

처음에는 인증이나 비밀번호 기능을 넣을 생각이 없었다.

하지만 그냥 클릭만으로 아무나 업데이트하고 삭제하면 

많이 불편해 보여 하나의 장치는 있어야 할 것 같았다.

세션이나 해시는 사용하기 간단해서 좋았다.