인증(Authentication) & 인가(Authorization)

황인용·2020년 1월 23일
0

인증인가

목록 보기
1/1

인증(Authentication)

  • Authentication은 유저의 identification을 확인하는 절차
  • 다시말해, 유저의 아이디와 비밀번호를 확인하는 절차
  • 인증을 하기 위해선 먼저 유저의 아이디와 비밀번호를 생성할 수 있는 기능도 필요하다

로그인 절차

  1. 유저 회원가입 => 이디와 비밀번호 생성. 비밀번호 암호화저장.
  2. 유저 비밀번호 암호화 해서 Database에 저장.
  3. 유저 로그인 => 아이디와 비밀번호 입력
  4. 유저가 입력한 비밀번호를 암호화 한 후, DB에서 암호화된 비밀번호와 비교.
  5. 일치하면 로그인 성공, 일치하지 않으면 Error.
  6. 로그인 성공하면 access_token을 클라이언트에게 전송
  7. 유저는 로그인 성공후 다음부터는 access_token을 첨부해서 request를 서버에 전송함.(매번 로그인 하지 않아도 됨)

유저 비밀번호 암호화

  • 유저의 비밀번호는 절대 비밀번호 그대로 Database에 저장하지 않는다
    - Database가 해킹을 당할 경우 비밀번호가 그대로 유출되기 때문.
    • 외부 해킹이 아니더라도 내부 개발자나 인력이 유저들의 비밀번호를 볼 수 있는 취약점 존재
  • 유저의 비밀번호는 반드시 암호화 해서 저장.
    - Database가 해킹당하더라도 비밀번호가 그대로 노출되지 않음.
    • 내부 인력도 비밀번호를 알 수 가 없음
  • 비밀번호 암호화에는 단방향 해쉬 함수(one-way hash function)가 일반적으로 사용
    - 단방향 해쉬 함수(one-way hash function)
    : 원본메세지를 변환하여 암호화된 메세지인 다이제스트(digest)를 생성한다. 암호화된 메세지로는 원본메세지를 구할 수 없어서 단방향성(one-way)이라고 한다.
    (ex. "testpassword"를 "hash256"로 해쉬 함수를 사용하면, "0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e"라고 나온다
    만약 "testwpassword2"를 똑같이 "hash256"로 해쉬 함수를 사용하면, "d34b32af5c7bc7f54153e2fdddf251550e7011e846b465e64207e8ccda4c1aeb"라는 값이 나온다 따라서 원본 비밀번호는 비슷하지만, 해쉬값은 완전히 다른 값이 나와 해킹하더라도 정보를 쉽게 알려줄수 없도록 도와준다)
In [21]: import hashlib

    In [22]: m = hashlib.sha256()

    In [23]: m.update(b"test password")

    In [24]: m.hexdigest()
    Out[24]: '0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e'

    In [25]: m = hashlib.sha256()

    In [26]: m.update(b"test password2")

    In [27]: m.hexdigest()
    Out[27]: 'd34b32af5c7bc7f54153e2fdddf251550e7011e846b465e64207e8ccda4c1aeb'

Bcrypt

  • 단방향 해쉬 함수에는 몇가지 취약점이 존재
    - Rainbow table attack - 미리 해쉬값들을 계산해 놓은 테이블(Rainbow Table)을 통해 암호화값이 맞을 때까지 공격함
    • Blueforce attack
  • 따라서 2가지 보완점 필요
    - Salting
    : 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해시값을 계산함
    • Key Strethcing
      : 단방향 해쉬값을 계산한 후 그 해쉬값을 여러번(Iteration count) 해쉬하는 것.

image.png

  • Bcrypt 암호화
    : Salting과 Key Stretching을 구현한 해쉬 함수중 가장 널리 사용되는 것 중 하나.
In [40]: import bcrypt

In [41]: bcrypt.hashpw(b"secrete password", bcrypt.gensalt())
Out[41]: b'$2b$12$.XIJKgAepSrI5ghrJUaJa.ogLHJHLyY8ikIC.7gDoUMkaMfzNhGo6'

In [42]: bcrypt.hashpw(b"secrete password", bcrypt.gensalt()).hex()
Out[42]: '243262243132242e6b426f39757a69666e344f563852694a43666b5165445469397448446c4d366635613542396847366d5132446d62744b70357353'

JWT(JSON Web Token)

  • 유저가 로그인 성공한 후에는 access_token이라고 하는 암호화된 유저정보를 첨부해서 response를 받게된다.
  • 유저 로그인
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json

{
    "username": "joe",
    "password": "pass"
}
  • access_token
HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}
  • 로그인에 성공한 유저는 다시 로그인하는 것이 아니라, access_token을 request 메세지에 넣어 서버에 보낸다.
  • acces_token을 받은 서버는 복호화를 걸쳐, 해당 유저 정보가 database에 있는지 확인한다.

image.png

  • JSON 데이터를 암호화하여 클라이언트-서버 간에 주고 받는 것을 JWT(JSON Web Token)이라 한다.

인가(Authorization)

  • Authorization은 유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차
    (ex. 해당유저는 고객 정보를 볼 수 있지만 수정할 권한이 없는 경우)
  • Authorizationeh JWT를 통해서 구현이 가능하다.

Authorization 절차

  1. Authorization 절차를 통해 access_token을 생성한다. acces_token에는 유저 정보를 확인 할 수 있는 정보가 들어가 있어야 한다.(ex. user id)
  2. 유저가 request를 보낼때 access_token을 첨부해서 보낸다.
  3. 서버에서는 유저가 보낸 access_token을 복호화 한다.
  4. 복호화된 데이터를 통해 user id를 얻는다.
  5. user id를 사용해서 database에서 해당 유저의 권한(permission)을 확인한다.
  6. 유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.
  7. 유저가 권한을 가지고 있지 않으면, Unauthorized Response(401) 혹은 다른 에러 코드를 보낸다.
profile
dev_pang의 pang.log

0개의 댓글