토큰 , JWT

Dayeon myeong·2021년 2월 3일
1

백엔드공부

목록 보기
2/3

토큰(token)

  • Stateless(무상태) : 상태 유지를 하지 않음 -> 클라이언트에 저장하기 때문에

  • Extensibility(확장성) : 다른 서비스에서도 권한을 공유 할 수 있음

  • 유저의 인증 정보를 서버 /세션 / 쿠키에 저장하지 않아 손쉽게 서버 확장 가능

  • 토큰 기반 시스템에서는, 토큰에 선택적인 권한만 부여하여 발급을 할 수 있음

  • 모바일 애플리케이션에 적합하며 인증 정보를 다른 애플리케이션에 전달 가능(OAuth)

  • 그 어떤 디바이스에서도,그 어떤 도메인에서도, 토큰만 유효하다면 요청이 정상적으로 처리 됨

JWT

  • 인증에 필요한 정보들(JSON 객체)을 암호화 시킨 토큰
  • Access Token(JWT 토큰)을 HTTP 헤더 / URL 파라미터에 실어 서버로 보내게 됨
  • 다양한 프로그래밍 언어(C,Java,PHP,JavaScript,Swift ,, )에서 지원
  • 자가 수용적(self-contained) : 필요한 정보를 자체적으로 지니고 있음
    • 토큰에 대한 기본 정보, 전달할 정보, 그리고 토큰이 검증됐다는 것을 증명해주는 signature
    • 토큰 자체가 인증 정보를 가지고 있기 때문에 민감한 정보는 인증서버에 다시 접속하는 과정이 필요
  • jwt 구조
    • header : 토큰 타입과 해싱 알고리즘이 들어감 (해싱 알고리즘에는 HMAC,SHA256, RSA 등이 있고 이 알고리즘은 토큰을 검증할 때 사용되는 signature 부분에서 사용됨)
    • payload : 토큰에 담을 정보가 들어있음
      • 정보의 한 조각을 클레임(claim)이라 부르고, name/value 의 한 쌍으로 이루어져있다. 클레임의 종류는 크게 세분류(등록된 / 공개 / 비공개 클레임)로 나뉨
        • "등록된 클레임"은 서비스에서 필요한 정보들이 아니라 토큰에 대한 정보들을 담기 위해 이름이 이미 정해진 클레임들입니다.
          • iss : 토큰 발급자 (issuer)
          • exp : 토큰의 만료시간 (expiration)
          • iat : 토큰이 발급된 시간(issued at), 토큰의 age가 얼마나 되었는지 판단 가능
    • signature : 토큰 유효성 검증을 위해 서명 검증
      • 헤더 인코딩 값 + 정보 인코딩 값 + 주어진 비밀키로 해싱

title

  • refresh token
    • Access Token(JWT)를 통한 인증 방식은 제 3자에게 탈취당할 경우 보안에 취약
    • access token 토큰 유효기간이 길면 탈취당할 수 있음
    • access token 유효 기간이 짧으면 로그인 자주해야하는 불편
    • Refresh Token은 Access Token과 똑같은 형태의 JWT(긴 유효기간 가짐, 대부분 2주)
    • access token이 만료되었을 때 refresh token을 이용해 새로 access token을 발급해준다
    • 처음에 로그인을 완료했을 때 access token과 동시에 발급됨
    • ex) 로그인 API, POST /api/auth/signin 호출(request body에 입력 아이디와 비밀번호 ), 응답 성공 시
    {
        "status": 200,
        "success": true,
        "message": "토큰 발급 완료.",
        "data": {
            "token": {
                "token": "..",
                "refreshToken": "...."
            }
        }
    }
  • ex) 로그인 API, POST /api/auth/signin 호출(request body에 입력 아이디와 비밀번호), 응답 실패시
    {
        "status": 400,
        "success": false,
        "message": "토큰값이 존재하지 않습니다."
    }

비밀번호 암호화

  • 웹사이트에서 SHA-256과 같은 해쉬 함수를 이용해 패스워드를 암호화해 저장하고 값을 비교하는 데 여기에도 두가지 문제가 있음
  • 인식 가능성(recognizability) :동일한 메시지가 언제나 동일한 다이제스트를 갖는다면, 공격자가 전처리(pre-computing)된 다이제스트를 가능한 한 많이 확보한 다음 이를 탈취한 다이제스트와 비교해 원본 메시지를 찾아내거나 동일한 효과의 메시지를 찾을 수 있다. 이와 같은 다이제스트 목록을 레인보우 테이블(rainbow table)이라 하고, 이와 같은 공격 방식을 레인보우 공격(rainbow attack)이라 한다. 게다가 다른 사용자의 패스워드가 같으면 다이제스트도 같으므로 한꺼번에 모두 정보가 탈취될 수 있다
  • 속도(speed) : 해쉬함수는 원래 짧은 시간에 데이터를 검색하기 위해 설계된 것. 이 빠른 처리 속도로 인해 공격자는 매우 빠르게 임의 문자열 다이제스트와 해킹할 대상의 다이제스트를 비교할 수 있다. 이런 방식으로 패스워드가 충분히 길거나 복잡하지 않은 경우에는 공격하는데 그리 긴 시간이 걸리지 않다.
  • 단방향 해시 함수 보완하기
    • salting(솔팅) : 솔트(salt)는 단방향 해시 함수에서 다이제스트를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다. 그리고 이 원본 메시지에 문자열을 추가하여 다이제스트를 생성하는 것을 솔팅(salting)이라 한다. 공격자가 다이제스틀 알아내도 패스워드 일치 여부 확인이 어렵다. 또한 사용자별로 다른 솔트를 사용한다면 동일한 패스워드를 동일한 패스워드를 사용하는 사용자의 다이제스트가 다르게 생성되어 인식 가능성 문제가 크게 개선 → 솔트와 암호화된 패스워드(다이제스트)를 데이터베이스에 저장, 사용자가 로그인할 때 입력한 패스워드를 해시하여 일치 여부를 확인
    • 키 스트레칭(key stretching) : 입력한 패스워드의 다이제스트를 생성하고, 생성된 다이제스트를 입력 값으로 하여 다이제스트를 생성하고, 또 이를 반복하는 방법으로 다이제스트를 생성할 수도 있다. 이렇게 하면 입력한 패스워드를 동일한 횟수만큼 해시해야만 입력한 패스워드의 일치 여부를 확인할 수 있다. 기본적인 키 스트레칭 과정
    • adaptive key derivation function (bcrypt,scrypt,,) : 다이제스트를 생성할 때 솔팅과 키 스트레칭을 반복하며 솔트와 패스워드 외에도 입력 값을 추가하여 공격자가 쉽게 다이제스트를 유추할 수 없도록 하고 보안의 강도를 선택할 수 있다.
profile
부족함을 당당히 마주하는 용기

0개의 댓글