인증
과 인가
는 API에서 가장 자주 구현되는 기능중 하나다.
Private한 API는 물론이고 Public한 API도 기본적인 인증과 인가를 요구한다.
access token
을 클라이언트에게 전송access token
을 첨부해서 request를 서버에 전송함으로서 매번 로그인 할 필요없게 만든다.다이제스트(digest)
를 생성한다. 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어서 단방향성(one-way)
이라고 한다.0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e
값이 나온다.d34b32af5c7bc7f54153e2fdddf251550e7011e846b465e64207e8ccda4c1aeb
값이 나온다. 실제 비밀번호는 비슷하지만 해쉬 함수 값은 완전히 다르다. 이런 효과를 avalance
라고 하는데 비밀번호 해쉬 값 해킹을 어렵게 만드는 요소 중 하나다. 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'
Rainbow table attack
미리 해쉬값들을 계산해 놓은 테이블을 Rainbow table
이라고 한다.
단방향 해쉬 함수도 몇가지 취약점이 있다.
단방향 해쉬 함수의 취약점들을 보안하기 위해 일반적으로 2가지 보완점들이 사용된다.
Salting
Key stretching
Salting
과 Key Stretching
을 구현한 해쉬 함수 중 가장 널리 사용되는 것이 bcrypt
이다. bcrypt
는 처음부터 비밀번호를 단방향 암호화 하기 위해 만들어진 해쉬함수다.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'
앞서 언급했듯이 유저가 로그인에 성공한 후에는 access token
이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
유저 로그인
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
을 복호화 해서 해당 유저 정보를 얻게 된다.
access token
인eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E
를 복호화 하면 이런 정보를 얻는다.{
user_id = 1
}
access token
을 생성하는 방법 중 가장 널리 사용되는 기술 중 하나가 JWT(JSON Web Tokens)
이다.
JWT는 유저 정보를 담은 JSON 데이터를 암호화해서 클라이언트와 서버간에 주고 받는 것이다.
access token
을 통해 해당 유저 정보를 얻을 수 있음으로 해당 유저가 가지고 있는 권한(permisson)도 확인 할 수 있다.access token
을 생성한다. access token
에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다. (ex: user id)access token
을 첨부해서 보낸다.access token
을 복호화 한다.