[TIL] 인가와 인증

minami·2021년 12월 22일
0

wecode

목록 보기
5/10

1. 인가 (Authorisation)

유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인지 확인하는 절차

  • 인가도 JWT를 통해서 구현 가능
    • access token을 통해 해당 유저 정보를 얻을 수 있으므로 해당 유저가 가지고 있는 권한(permission)도 확인 가능

인가 절차

  1. 인가 절차를 통해 access token 생성
    • access token에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다. (ex. userId)
  2. 유저가 request를 보낼 때 access token 첨부
  3. 서버에서 유저가 보낸 access token 복호화
  4. 복호화된 데이터를 통해 userId를 얻는다.
  5. userId를 사용하여 DB에서 해당 유저의 권한(permission) 확인
  6. 유저가 충분한 권한을 가지고 있으면 해당 요청 처리
    1. 유저가 권한을 가지고 있지 않으면 Unauthorised Response(401) 혹은 다른 에러 코드 전송

2. 인증 (Authentication)

유저의 identification을 확인하는 절차 = 유저의 아이디와 비밀번호 확인 절차

2-1. 로그인 절차

  1. 유저 아이디와 비밀번호 생성
  2. 유저 비밀번호를 암호화하여 DB에 저장
  3. 유저가 아이디와 비밀번호를 입력하여 로그인
  4. 유저가 입력한 비밀번호를 암호화하여 DB에 저장된 암호화된 비밀번호와 비교
  5. 일치하면 로그인 성공
  6. 로그인에 성공하면 access token을 클라이언트에게 전송
  7. 유저가 로그인에 성공한 다음부터는 access token을 첨부하여 request를 전송해서 매번 로그인을 하지 않아도 되도록 한다.

2-2. 유저 비밀번호 암호화

  • 유저의 비밀번호는 반드시 암호화하여 저장한다.
  • 일반적으로 비밀번호 암호화에는 단방향 해시 함수(One-way Hash Function) 사용
    • 단방향 해시 함수는 원본 메시지를 변환하여 암호화된 메시지인 다이제스트(digest)를 생성한다. 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어서 단방향성(one-way)라고 한다.

2-3. 단방향 해시 함수

  • 단방향 해시 함수의 취약점

    • Rainbow Table Attack: 미리 해시값들을 계산해 놓은 테이블을 이용한 공격

    • 해시 함수는 원래 패스워드를 저장하기 위해 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것으로, 빠른 처리 속도 때문에 공격자도 매우 빠른 속도로 임의의 문자열의 다이제스트와 해킹할 대상의 다이제스트를 비교할 수 있다.

      ex. MD5를 사용할 경우 일반적인 장비로도 1초당 56억개의 다이제스트 대입 가능

  • 단방향 해시 함수의 취약점 보완

    • Salting: 실제 비밀번호 외에 추가적으로 랜덤 데이터를 더해서 해시값을 계산하는 방법
    • Key Stretching: 단방향 해시값을 계산한 후 그 해시값을 다시 반복적으로 해싱하는 것. 최근에는 키 스트레칭을 적용하여 동일한 장비에서 1초에 5번 정도만 비교할 수 있도록 한다. GPU를 사용하더라도 수백~수천 번 정도만 비교할 수 있도록 하였다.

bcrypt

SaltingKey Stretching을 구현한 해시 함수 중 가장 널리 사용되며 처음부터 비밀번호를 단방향 함호화하기 위해 만들어진 해시 함수

JWT

JSON Web Token

  1. JWT 토큰의 구조

  1. 헤더(Header)

    • 두 가지의 정보를 갖고 있다.
      • typ: 토큰의 타입인 JWT
      • alg: 해싱 알고리즘 지정
  2. 내용(Payload)

    • Registered Claim: 만료시간을 나타내는 exp처럼 미리 정의된 집합

    • Public Claim: 공개용 정보 전달 목적

    • Private Claim: 클라이언트와 서버간 협의하에 사용

    • 위 3가지 요소를 조합하여 작성한 후 BASE64로 인코딩하여 두 번째 요소로 위치

      ex) { "user-id": 1, "exp": 1539517391 }

  3. 서명(Signature)

    • JWT가 원본 그대로라는 것을 확인할 때 사용
    • BASE64로 인코딩된 header와 payload, JWT secret(별도 생성)을 헤더에 지정된 암호 알고리즘으로 암호화하여 전송(복호화 가능)
    • 프론트엔드가 JWT를 백엔드 API 서버로 전송하면 서버에서는 전송받은 JWT의 서명을 복호화하여 서버에서 생성한 JWT가 맞는지 확인
    • 계약서의 위변조를 막기 위해 서로 서명하는 것과 같다.
    • ❗❗ header와 payload는 BASE64 인코딩한 것이므로 누구나 원본을 볼 수 있으므로 개인정보를 담아서는 안 된다.
profile
함께 나아가는 개발자💪

0개의 댓글