[인증/보안] Hashing, Token, JWT

Hyun Jin·2023년 3월 8일
0

1. 해싱 (Hashing)

해싱이란?

  • 가장 많이 쓰이는 암호화 방식 중 하나. 복호화가 가능한 다른 암호화 방식들과 달리, 해싱은 암호화만 가능함.(복호화가 불가능!!)
  • 해싱은 해시 함수(Hash Function)을 사용하여 암호화를 진행함.

Salt

  • 그러나 해시 함수는 동일한 값을 넣으면 항상 같은 결과값을 리턴함 -> 결과값과 해싱 이전 값을 기록해놓은 레인보우 테이블에 기록된 값의 경우 보안 상 위협이 될 수 있음.
  • 그래서 Salt(secret)를 사용하여 해싱 이전 값에 임의의 값을 더해서 해싱 값이 유출되더라도 암호화 이전 값을 알아내기 어렵게 만듬.

해싱의 목적

  • 데이터 그 자체를 사용하는 것이 아니라, 데이터가 동일한지 여부만을 확인하는 것이 목적임. 그래서 복호화가 불가능해도 됨.
    오히려 복호화가 불가능해서 사이트 관리자가 사용자의 로그인정보를 악용하는 등의 가능성을 없앨 수 있음.
  • 서버 측에서는 해싱한 값끼리 비교해서 일치하는지 여부를 확인하여 로그인 요청 등을 처리함.
  • 민감한 데이터를 다루어야 하는 상황에서 데이터 유출의 위험성은 줄이면서 데이터의 유효성을 검증하기 위해서 사용되는 단방향 암호화 방식임.

2. 토큰 (Token)

토큰이란?

클라이언트가 인증정보를 보관하게 해주는 수단.
인증과 권한 정보를 담고 있는 암호화된 문자열로, 놀이공원 입장권, 사무실 출입카드 같은 것임.
토큰 방식은 세션 기반 인증 시의 서버의 부담을 줄여주기 위해 나온 방식.

토큰 인증방식의 흐름

  1. 클라이언트가 서버에 접속하면 서버에서 데이터베이스에 저장된 사용자의 인증정보를 확인하고, 인증이 성공했을 경우 해당 클라이언트에서 인증되었다는 의미로 ‘토큰’을 부여한다.
    이 토큰에는 해당 사용자의 인증정보, 권한정보가 서버의 비밀키와 함께 암호화 되어 있다.
  2. 생성된 토큰을 HTTP 헤더나 쿠키를 사용해서 클라이언트로 전달한다.
  3. 이 토큰은 유일하며, 토큰을 발급받은 클라이언트는 이 토큰을 쿠키나 스토리지에 저장해두고, 다음에 서버에 요청을 보낼 때 HTTP 요청 헤더나 쿠키를 사용해서 토큰을 같이 보낸다.
  4. 서버에서는 클라이언트로부터 받은 토큰이 서버에서 제공한 토큰과 일치하는지 확인하여(서버의 비밀키를 통해 검증함) 유효한 토큰인 경우 응답 데이터를 전송한다.

토큰 인증 방식의 장점

1. 무상태성
서버가 유저의 인증상태를 관리하지 않으므로(클라이언트가 보낸 토큰의 유효성만 검증) 무상태적인 구조를 구축할 수 있음.

2. 확장성
무상태성 -> 서버 확장에 용이함

3. 어디서나 토큰 생성이 가능함
토큰의 생성과 검증이 하나의 서버에서 이루어지지 않아도 되기 때문에 토큰 생성만을 담당하는 서버를 구축 가능함.

4. 권한 부여에 용이함
토큰은 인증 상태, 접근 권한 등 다양한 정보를 담을 수 있기 때문에 사용자 권한 부여에 용이함

JWT (JSON Web Token)

토큰 기반 인증 구현 시 대표적으로 사용하는 기술
JSON 객체에 정보를 담고 이를 토큰으로 암호화하여 전송할 수 있는 기술
클라이언트가 서버에 요청을 보낼 때 인증정보를 암호화된 JWT 토큰으로 제공하고, 서버는 이 토큰을 검증하여 인증정보를 확인 가능함

JWT의 구성

1. Header
토큰의 종류, 암호화에 사용한 알고리즘을 JSON 형태로 담고 있음.

{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload
전달하려는 데이터를 JSON 형태로 담고 있음.(유저 정보, 접근 권한, 토큰의 유효기간 등)

{
  "sub": "payloadInformation",
  "name": "Jane",
  "iat": 14336547
}

3. Signature
토큰의 무결성을 확인할 수 있는 부분.
Header와 Payload가 완성되었다면, Signature는 이를 서버의 비밀 키(암호화에 추가할 salt)와 Header에서 지정한 알고리즘을 사용하여 해싱함
Header, Payload 를 base64로 인코딩한 값과 salt 값(secret)의 조합으로 암호화한 값
서버에서 제대로된 토큰을 검증하는 과정 : Header, Payload 를 서버에서 다시 암호화해서 받은 signature 와 같으면 검증이 된 유효한 토큰으로 봄!

HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

토큰 인증 방식의 한계

1. 무상태성
서버가 인증 상태를 관리하지 않음 -> 토큰이 탈취되어도 서버가 강제로 토큰을 만료시킬 수 없음.

2. 유효기간
유효기간이 짧으면 : 토큰 탈취상황에 대비가능하지만 사용자는 토큰이 만료될 때마다 다시 로그인을 해야 하기에 사용자 경험이 떨어짐
유효기간이 길면 : 토큰이 탈취될 경우 더 치명적일 수 있음

3. 토큰의 크기
토큰에 여러 정보를 담을 수 있는 만큼, 데이터가 많아질수록 암호화 과정이 길어지고 토큰의 크기가 커져서 네트워크 비용 문제가 발생할 수 있음.

토큰의 종류

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

2. 리프레시 토큰
액세스 토큰 재발급용 토큰. 보통 액세스 토큰보다 유효기간을 길게 설정함.

profile
새싹 프론트엔드 개발자

0개의 댓글