S3U7 [Backend] Hashing/Token

전형호·2023년 3월 8일
0

✏️ 학습 목표

  • Hashing이 필요한 이유에 대해 이해한다.
  • 데이터베이스에 유저의 비밀번호와 같이 민감한 정보를,
  • 평문으로 저장하지 않는 이유에 대해 이해한다.
  • Salt가 필요한 이유에 대해 이해한다.
  • 토큰의 개념을 이해할 수 있다.
  • Refresh Token과 Access Token의 차이를 이해한다.
  • 쿠키 / 세션 방식과 토큰 방식의 차이를 이해할 수 있다.
  • JWT의 작동원리에 대해 이해할 수 있다.
  • header, payload, signature가 각각 어떤 역할을 하는 지 이해할 수 있다.
  • JWT가 어떻게 토큰의 변조를 판별하는 지 이해할 수 있다.
  • 토큰 방식의 한계를 이해할 수 있다.

🔊 Hashing

  • 복호화가 가능한 다른 암호화 방식들과 달리, 해싱은 암호화만 가능하다.

✅ 해시 함수 특징

  • 항상 같은 길이의 문자열을 리턴한다.

  • 서로 다른 문자열에 동일한 해시 함수를 사용하면 반드시 다른 결과값이 나온다.

  • 동일한 문자열에 동일한 해시 함수를 사용하면 항상 같은 결과값이 나온다.

  • 해시 함수중 하나인 SHA1에 특정 입력 값을 넣었을 때,

  • 어떤 결과가 리턴되는지 보여주는 예시다.

✅ 레인보우 테이블과 솔트

  • 레인보우 테이블에 기록된 값의 경우에는 유출이 되었을 때,
  • 해싱을 했더라도 해싱 이전의 값을 알아낼 수 있으므로 보안상 위협이 될 수 있다.
  • 이 때 활용할 수 있는 것이 솔트이다.
    • 해싱 이전 값에 임의의 값을 더해 데이터가 유출 되더라도,
    • 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법이다.
    • 솔트를 사용하게 되면 해싱 값이 유출되더라도,
    • 솔트가 함께 유출 된 것이 아니면 암호화 이전의 값을 알아내는 것은 어렵다.

✅ 해싱의 목적

  • 데이터 그 자체를 사용하는 것이 아니라,
  • 동일한 값의 데이터를 사용하고 있는지 여부만 확인하는 것이다.
  • 민감한 데이터를 다루어야 하는 상황에서 데이터 유출의 위험성은 줄이면서,
  • 데이터의 유효성을 검증하기 위해서 사용되는 단방향 암호화 방식이다.


🔊 토큰 인증 방식

  • 최근 웹 애플리케이션에서 많이 사용되는 인증 방식 중 하나이다.
  • 토큰을 사용하면 사용자의 인증 정보를 서버가 아닌 클라이언트 측에 저장할 수 있다.

✅ 토큰

  • 사용자 인증 정보와 권한 정보를 포함한 정보를 담은 암호화된 문자열이다.

✅ 토큰 인증 방식 흐름

  1. 사용자가 인증 정보를 담아 서버에 로그인 요청을 보낸다.

  2. 서버는 데이터베이스에 저장된 사용자의 인증 정보를 확인한다.

  3. 인증에 성공했다면 해당 사용자의 인증 및 권한 정보를 서버의 비밀 키와 함께 토큰으로 암호화한다.

  4. 생성된 토큰을 클라이언트로 전달한다.

    • HTTP 상에서 인증 토큰을 보내기 위해 사용하는 헤더인 Authorization 헤더를 사용하거나, 쿠키로 전달하는 등의 방법을 사용한다.
  5. 클라이언트는 전달받은 토큰을 저장한다.

    • 저장하는 위치는 Local Storage, Session Storage, Cookie 등 다양하다.
  6. 클라이언트가 서버로 리소스를 요청할 때 토큰을 함께 전달합니다.

    • 토큰을 보낼 때에도 Authorization 헤더를 사용하거나 쿠키로 전달할 수 있습니다.
  7. 서버는 전달받은 토큰을 서버의 비밀 키를 통해 검증한다. 이를 통해 토큰이 위조되었는지 혹은 토큰의 유효 기간이 지나지 않았는지 등을 확인할 수 있습니다.

  8. 토큰이 유효하다면 클라이언트의 요청에 대한 응답 데이터를 전송한다.

✅ 토큰 인증 방식 흐름 장점

* 무상태성

  • 서버가 유저의 인증 상태를 관리하지 않는다.

* 확장성

  • 다수의 서버가 공통된 세션 데이터를 가질 필요가 없다.
  • 서버를 확장하기 더 용이하다.

* 어디서나 토큰 생성 가능

  • 토큰의 생성과 검증이 하나의 서버에서 이루어지지 않아도 된다.
  • 토큰 생성만을 담당하는 서버를 구축할 수 있다.
  • 러 서비스 간의 공통된 인증 서버를 구현할 수 있다.

* 권한 부여에 용이

  • 토큰은 인증 상태, 접근 권한 등 다양한 정보를 담을 수 있기 때문에,
  • 사용자 권한 부여에 용이하다.
  • 어드민 권한 부여 및 정보에 접근할 수 있는 범위도 설정할 수 있다.


🔊 JWT

  • SON 객체에 정보를 담고 이를 토큰으로 암호화하여 전송할 수 있는 기술이다.
  • 클라이언트가 서버에 요청을 보낼 때, 인증정보를 암호화된 JWT 토큰으로,
  • 제공하고, 서버는 이 토큰을 검증하여 인증정보를 확인할 수 있다.

✅ JWT의 구성

  • 나누어진 세 부분이 존재하며 Header, Payload, Signature라고 부른다.

✅ Header

{
  "alg": "HS256",
  "typ": "JWT"
}
  • HTTP의 헤더처럼 해당 토큰 자체를 설명하는 데이터가 담겨 있다.
  • 토큰의 종류, 시그니처를 만들 때 사용할 알고리즘을 JSON 형태로 작성한다.
  • JSON 객체를 base64 방식으로 인코딩하면,
  • JWT의 첫 번째 부분인 Header가 완성된다.
    • base64 방식은 원한다면 얼마든지 디코딩할 수 있는 인코딩 방식이다.

✅ Payload

{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}
  • HTTP의 페이로드와 마찬가지로 전달하려는 내용물을 담고 있는 부분이다.
  • 어떤 정보에 접근 가능한지에 대한 권한, 유저의 이름과 같은 개인정보,
  • 토큰의 발급 시간 및 만료 시간 등의 정보들을 JSON 형태로 담는다.
  • JSON 객체를 base64로 인코딩하면 JWT의 두 번째 부분인 Payload가 완성된다.

✅ Signature

  • 토큰의 무결성을 확인할 수 있는 부분이다.
  • HeaderPayload가 완성되었다면, Signature는,
  • 서버의 비밀 키와 Header에서 지정한 알고리즘을 사용하여 해싱한다.
  • 서버는 Signiture를 검증하는 단계에서 올바르지 않은 토큰임을 알아낼 수 있다.

✅ 토큰 인증 방식의 한계

* 무상태성

  • 토큰이 만료될 때까지 사용자로 가장해 계속해서 요청을 보낼 수 있다.

* 유효 기간

  • 토큰이 탈취되는 상황을 대비해서 유효 기간을 짧게 설정하면,
  • 사용자는 토큰이 만료될 때마다 다시 로그인을 진행해야 하기 때문에 좋지 않은 사용자 경험을 제공한다.
  • 유효 기간을 길게 설정하면 토큰이 탈취될 경우 더 치명적으로 작용할 수 있다.

* 토큰의 크기

  • 토큰에 여러 정보를 담을 수 있는 만큼, 많은 데이터를 담으면,
  • 그만큼 암호화하는 과정도 길어지고 토큰의 크기도 커지기 때문에,
  • 네트워크 비용 문제가 생길 수 있다.

✅ 액세스 토큰과 리프레시 토큰

* Access Token

  • 서버에 접근하기 위한 토큰이다.
  • 안을 위해 보통 24시간 정도의 짧은 유효기간이 설정되어 있다.

* Refresh Token

  • 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰이다.
  • 리프레시 토큰은 액세스 토큰보다 긴 유효기간을 설정한다.
profile
코드스테이츠 블로그

0개의 댓글