WEB

인증 (Authentication)

on 

인증

Authentication

유저의 identification 을 확인하는 절차

회원가입과 로그인 절차에서 유저의 비밀번호를 데이터베이스에 저장하고 이를 확인하는 인증의 과정이 필요합니다. 이때 유저의 비밀번호를 그대로 데이터베이스에 저장할 경우, 해킹 시 비밀번호가 그대로 노출되며 내부 인력이 유저의 비밀번호를 조회할 가능성이 있습니다. 이처럼 비밀번호와 관련된 여러 가지 보안상 문제를 방지하기 위하여 암호화하여 저장하고 관리할 필요가 있고 법 규정1으로 이를 강제하고 있습니다.

먼저 회원가입과 로그인의 절차는,

  1. 유저가 아이디와 비밀번호를 생성
  2. 유저의 비밀번호를 암호화하여 데이터베이스에 저장
  3. 유저가 아이디와 비밀번호를 입력
  4. 비밀번호를 암호화한 후 데이터베이스에 저장된 암호화된 비밀번호와 비교 (일치하면 로그인 성공)
  5. 로그인에 성공하면 access token을 전송
  6. 이후 모든 request에 access token을 함께 전송 → 인가2

위와 같은 순서로 진행됩니다. 위 과정에서 암호화와 토큰 발행 두 가지의 과정을 통해 인증과 인가를 진행합니다.

비밀번호 암호화

해싱(Hashing)암호화(Encryption) 둘 다 데이터 보안을 위해 사용됩니다. 비밀번호를 암호화하기 위하여 두 가지 방식을 비교해볼 때 가장 큰 차이점은 방향입니다. 해시 함수는 일방향 암호화이며 복호화가 불가능하고 암호화는 양방향 암호화로 복호화가 가능합니다. 전자의 경우 주로 데이터의 노출을 막는 데 목적이 있고 후자는 서버와 브라우저의 통신에서 주고받는 데이터의 암호화에 목적을 두고 있습니다. 비밀번호의 경우 복호화되지 아니하도록 해시를 통해 일방향 암호화를 합니다.

일방향 해시 함수 (one-way hash function)

>>> import hashlib
>>> h = hashlib.sha256()
>>> h.update(b'test password')
>>> h.hexdigest()
'0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e'

>>> h.update(b'test password 2')
>>> h.hexdigest()
'55192b4b915c37be114310c37e4736ecdc10117242574283d9aec75c0814542a'

해시 함수

해시 함수는 입력 값의 길이에 상관없이 고정된 길이의 해시 값(digest)을 생성합니다. 이때 입력 값이 일부만 변경되더라도 완전히 다른 해시 값을 출력합니다. 또한 위에서 언급하였듯이 복호화할 수 없습니다.

해시 함수의 문제점

해시 함수의 문제점 보완

salting

해시 함수 종류

Bcrypt

bcrypt는 단방향 암호화 해시 함수로 1999년 USENIX에서 발표되었습니다.

$2b$[cost]$[22 character salt][31 character hash]

bcrypt의 해시 문자열은 위와 같은 형태로 출력됩니다.

각 부분을 살펴보면 다음과 같습니다.

$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
\__/\/ \____________________/\_____________________________/
 Alg Cost      Salt                        Hash

bcrypt 라이브러리를 사용하여 비밀번호를 암호화하고 일치 여부를 확인하는 과정입니다.

>>> import bcrypt
>>> password = 'test password'
>>> bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
'$2b$12$gqRWzJHEIVJh/NdyTH45zeBln0ybDqjfwe97dSCMPJQC0UPdV3Y96'

bcrypt는 str 데이터가 아닌 Byte 데이터를 암호화 합니다. 위처럼 bcrypt를 통해 암호화된 비밀번호를 얻습니다.

>>> password = 'test password'
>>> hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
>>> bcrypt.checkpw(password.encode('utf-8'),hashed_password)
True

비밀번호가 일치하는지 확인하기 위해서는 입력된 비밀번호와 해싱된 비밀번호를 checkpw()의 인자로 넘겨 일치 여부를 확인할 수 있습니다.

  1. 제 24조(고유식별정보의 처리 제한) ③ 개인정보처리자가 제 1 항 각 호에 따라 고유식별정보를 처리하는 경우에는 그 고유식별정보가 분실﹒도난﹒유출﹒위조﹒변조 또는 훼손되지 아니하도록 대통령령으로 정하는 바에 따라 암호화 등 안전성 확보에 필요한 조치를 하여야 한다. 

  2. request를 실행할 수 있는 권한이 있는 유저인지 확인하는 절차.