1. 인증(Authentication)
- 인증은 유저의 identification을 확인하는 절차입니다.
1-1. 로그인 절차
- 유저 아이디와 비번 생성
- 유저 비번 암호화해서 DB에 저장
- 유저 로그인 -> 아이디와 비밀번호 입력
- 유저가 입력한 비밀번호 암호화한 후 암호화돼서 DB에 저장된 유저 비밀번호와 비교
- 일치하면 로그인 성공
- 로그인 성공하면
access token
을 클라이언트에게 전송
- 유저는 로그인 성공후 다음부터는
access token
을 첨부해서 request를 서버에 전송함으로서 매번 로그인 하지 않도록 한다.
1-2. 유저 비밀번호 암호화
- 유저의 비밀번호는 절대 비밀번호 그대로 DB에 저장하지 않는다.
- DB가 해킹을 당하면 유저의 비밀번호도 그대로 노출된다.
- 외부 해킹이 아니더라도 내부 개발자나 인력이 유저들의 비밀번호를 볼 수 있다.
- 비밀번호 암호에는 단방향 해쉬 함수(one-way hash function)가 일반적으로 쓰인다.
- 단방향 해시 함수는 원본 메시지를 변환하여 암호화된 메시지인
다이제스트(digest)
를 생성한다.
- 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어서 단방향성(one-way)이라고 한다.
Avalanche Effect(눈사태 효과)
: 원문의 한 비트의 변화가 최종 암호문에 큰 변화를 주는 효과이다.
-> 비밀번호 해쉬 값 해킹을 어렵게 만드는 하나의 요소이다.
1-3. Bcrypt
- 단방향 해쉬 함수도 몇가지 취약점이 있다.
Rainbow table attack
: 미리 해쉬값들을 계산해 놓은 테이블을 Rainbow table이라고 한다.
- 해쉬 함수는 원래 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.
- 그렇기 때문에 해시 함수는 본래 처리 속도가 최대한 빠르도록 설계되었다. 이러한 속성 때문에 공격자는 매우 빠른 속도록 임의의 문자열의 다이제스트와 해킹할 대상의 다이제스트를 비교할 수 있다.
- 이런 방식으로 패스워드를 추측하면 패스워드가 충분히 길거나 복잡하지 않은 경우에는 그리 긴 시간이 걸리지 않는다.
- 단방향 해쉬 함수의 취약점들을 보완하기 위해 일반적으로 2가지 보완점들이 사용된다.
Salting
- 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해시값을 계산하는 방법
Key Stretching
단방향 해쉬값을 계산한 후 그 해쉬값을 또 해쉬하고, 또 이를 반복하는 것을 말한다.
최근에는 일반적인 장비로 1초에 50억개 이상의 다이제스트를 비교할 수 있지만, 키 스트레칭을 적용하여 동일한 장비에서 1초에 5번 정도만 비교할 수 있게 한다.
Salting
과 Key Stretching
을 구현한 해쉬 함수중 가장 널리 사용되는 것이 bcrypt이다. bcrypt는 처음부터 비밀번호를 단방향 암호화하기 위해 만들어진 해쉬함수이다.
1-4. JWT(JSON Web Tokens)
- 유저가 로그인에 성공한 후에는
access token
이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json
{
"username": "joe",
"password": "pass"
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}
- 서버에서는
access token
을 복호화해서 해당 유저 정보를 얻게 된다.
{
user_id = 1
}
- 복호화해서 얻은 유저 아이디를 통해 해당 유저가 누군지 알 수 있다.
-> 유저가 매번 로그인하지 않아도 된다.
access token
을 생성하는 방법은 여러가지가 있는데, 그 중 가장 널리 사용되는 기술중 하나가 바로 JWT(JSON Web Tokens)이다.
- JWT는 유저 정보를 담은 JSON데이터를 암호화해서 클라이언트와 서버간에 주고 받는 것이다.
2. 인가(Authorization)
2-1. 인가
- 인가는 유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차이다.
-> 해당 유저는 고객 정보를 볼 수는 있지만 수정할 수는 없다 등
- 인가도 JWT를 통해서 구현할 수 있다.
access token
을 통해 해당 유저 정보를 얻을 수 있으므로 해당 유저가 가지고 있는 권한(permission)도 확인할 수 있다.
2-2. Authorization 절차
- Authentication 절차를 통해
access token
을 생성한다. 여기에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다. (user id등)
- 유저가 request를 보낼때
access token
을 첨부해서 보낸다.
- 서버에서는 유저가 보낸
access token
을 복호화한다.
- 복호화된 데이터를 통해 user id를 얻는다.
- user id를 사용해서 database에서 해당 유저의 권한(permission)을 확인한다.
- 유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.
- 유저가 권한을 가지고 있지 않으면 Unauthorized Response(401) 혹은 다른 에러 코드를 보낸다.