S3. Token

Haizel·2023년 2월 13일
0

Front-End Developer 되기

목록 보기
65/70
post-thumbnail

01. Hashing


‼️ 해싱은 암호화만 가능하다.

  • 해싱은 가장 많이 쓰이는 암호화 방식 중 하나로, 복호화가 가능한 다름 암호화 방식과 달리, 해싱은 암호화만 가능하다.
  • 해싱은 해시 함수(Hash function)을 사용해 암호화를 진행하는데 → 해시 함수는 다음과 같은 특징을 가진다.
  1. 항상 같은 길이의 문제열을 리턴한다.
  2. 서로 다른 문자열에 동일한 해시 함수를 사용하면 → 반드시 다른 결과값이 나온다.
  3. 동일한 문자열에 동일한 해시함수를 사용하면 → 항상 같은 결과값이 나온다.

# 대표적인 해시 함수 중 하나인 SHA1

  • SHA1에 특정값을 넣었을 때 어던 결과가 리턴되는지 확인해보자
비밀번호해시 함수(SHA1) 리턴 값
‘password’‘5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8’
‘Password’‘8BE3C943B1609FFFBFC51AAD666D0A04ADF83C9D’
‘kimcoding’‘61D17C8312E8BC24D126BE182BC674704F954C5A’

🔨 1. 레인보우 테이블과 솔트(Salt)

🌈 레인보우 테이블

  • 레인보우 테이블은 : 해싱 함수의 특성인 항상 같은 결과값이 나온다는 것을 이용해 → 해시 함수를 거치기 이전의 값을 알아낼 수 있도록 기록해놓은 표를 말한다.
    • 레인보우 테이블에 기록된 값은 유출되었을 때 해싱을 했다 하더라도 해싱 이전의 값을 알아낼 수 있으므로 보안 상의 위협이 될 수 있다.
    • 이때 ! 활용할 수 있는 것이 솔트(Salt)이다.

🧂 솔트(Salt)

  • 솔트는 말 그래도 소금을 치듯 해싱 이전 값에 임의의 값을 더해 → 데이터가 유출되더라도 해싱 이전의 값을 알아내기 어렵게 만드는 방법을 말한다.
비밀번호 + 솔트해시 함수(SHA1) 리턴 값
‘password’ + ‘salt’‘C88E9C67041A74E0357BEFDFF93F87DDE0904214’
‘Password’ + ‘salt’‘38A8FDE622C0CF723934BA7138A72BEACCFC69D4’
‘kimcoding’ + ‘salt’‘8607976121653D418DDA5F6379EB0324CA8618E6’

🔨 2. 해싱의 목적

“ 데이터 그자체를 사용하는 것이 아니라, 동일한 값의 데이터를 사용하고 있는지 여부만 확인하는 것이 목적이다”

사용자가 로그인을 위해 아이디와 비밀번호를 사이트에 입력하는 경우를 예로 들어보자.

  • 보통 비밀번호를 데이터베이스에 저장할 때, 복호화가 불가능하도록 해싱하여 저장하게 된다.
  • 해싱은 복호화가 불가능하므로 사이트 관리자도 정확한 비밀번호를 알 수 없어 → 강력한 보안이 가능
  • 서버는 비밀번호를 몰라 어떻게 처리할까 라는 의문이 들겠지만 → 답은 해싱한 값끼리 비교해 일치하는지 확인하는 방법이 있다.
  • 꼭 정확한 값을 몰라도, 해싱한 값이 일치한다면 → 정확한 비밀번호를 입력했다는 뜻이므로 → 해싱 값으로만 로그인 요청을 처리 가능하다.

이처럼 해싱은 민감한 데이터를 다뤄야하는 상황에서 데이터 유출 위험성은 줄이고 && 데이터의 유효성을 검증할 수 있는 단반향 암호화 방식이다.


02. Token


  • 서버가 아닌 클라이언트에 인증정보를 보관하는 방법을 **토큰 기반 인증**이라고 한다.
  • 토큰은 유저 정보를 암호화해 클라이언트에 담는다.

🔨 1. JWT (Json Web Token)

  • JWT는 가장 대표적인 토큰기반 인증으로, 보통 두가지 종류의 토큰을 이용해 인증을 구현한다.

1. 엑서스 토큰(Access Token)

  • 엑세스 토큰은 보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한 부여에 사용한다.

클라이언트가 처음 인증을 받게 될 때(로그인 시) → 엑세스 토큰, 리프레시 토큰을 모두 받지만 실제 권한 얻는데 사용하는 토큰은 엑세스 토큰이다.

2. 리프레시 토큰(Refresh Token)

권한을 부여 받기 위해선 엑세서 토큰만 있으면 되지만 → 만약 이 엑세스 토큰이 탈취되었다면 어떡할까?

  • 탈취 위험이 있는 엑세스 토큰엔 비교적 짧은 유효기간을 주어 → 탈취가 되더라도 오랫동안 사용할 수 없도록 하는 것이 좋다.
  • 그리고 세스 토큰의 유효기간이 만료되면 → 리프레시 토큰을 사용해 새로운 액세스 토큰을 발급받는다.
  • 리프레시 토큰도 마찬가지로 탈취 위험이 존재하기 때문에 → 유저의 편의보다 정보를 지키는 것이 더 중요한 웹사이트는 리프레시 토큰을 이용하지 않기도 한다.

🔨 2. JWT 구조

  • JWT는 .으로 나눠진 세부분이 있고, 각 부분을 Header, Payload, Signature 라고 부른다.

1. Header

  • 이것이 어떤 종류의 토큰인지(JWT 등), 어떤 알고리즘으로 시그니처를 암호화(sign)할 건지 적혀있다.
  • JSON Web Token 이라는 이름처럼 JSON 형태로 정보다 담겨진다.
 {
  "alg" : "HS256" ,
  "typ" : "JWT"
  }

2. Payload

  • 서버에서 활용할 수 있는 유저의 정보가 담겨있다.
  • 어떤 정보에 접근권한이 있는지, 유저의 개인정보(이름 등) 등을 담을 수 있다.
  • 페이로드 속 정보는 디코딩이 쉬운 base64방식으로 인코딩 되기 때문에 너무 민감한 정보를 담지 않는 것이 좋다.
  • Header와 마찬가지로 `JSON 객체`를 base64로 인코딩 하면 → JWT의 Payload가 완성된다.
 {
  "sub" : "someInformation" ,
  "name" : "phillip" ,
  "iat" : 151623391
  }

3. Signature

  • base64로 인코딩된 Header와 Payload를 서버의 비밀 키(암호화에 추가할 salt)헤더에서 지정한 알고리즘( "alg" : "HS256")을 사용해 해싱한다.

누군가 Header와 Payload를 이용해 토큰을 위조하더라도, 서버의 비밀 키를 정확히 알지 못한다면 전혀 다른 Signature가 만들어짐으로 → 해당 토큰의 진위여부를 확인 할 수 있다.

🔨 3. JWT 사용 예시

  • JWT는 권한 부여에 굉장히 유용하다.
🤔 **예시 ) 새로받은 A 앱이 Gmail과 연동되어 이메일을 읽어와야한다.
  1. Gmail 인증서버에 로그인정보(아이디, 비밀번호)를 제공한다.
  2. 성공적으로 인증시 JWT를 발급받는다.
  3. A앱은 JWT를 사용해 해당 유저의 Gmail

🔨 4. 토큰 기반의 인증절차

  1. 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.
  2. 아이디/비밀번호가 일치하는지 확인하고 → 클라이언트에게 보낼 암호화된 토큰을 생성한다.
    • access/refresh 토큰을 모두 생성한다.
      • 토큰에 담길 정보(payload)는 유저를 식별할 정보, 권한이 부여된 카테고리(사진, 연락처, 기타 등등)이 될 수 있다.
      • 두 종류의 토큰이 같은 정보를 담을 필요는 없다.
  3. 서버가 토큰을 클라이언트에게 보내주면 → 클라이언트는 토큰을 저장한다.
    • 저장하는 위치는 Local Storage, Sesstion Storage, Cookie 등 다양하다.
  4. 클라이언트가 HTTP 헤더(Authorization 헤더) 또는 쿠키에 토큰을 담아 보낸다.
    • 쿠키에는 리프레시 토큰을, 헤더 또는 바디에는 액세스 토큰을 담는 등 다양항 방법으로 구현할 수 있다.
    • Authorization 헤더를 이용한다면 Bearer Authentication을 이용한다. 참
  5. 서버는 토큰을 해독하여 “우리가 발급해준 토큰이 맞네” 라는 판단이 되면 → 클라이언트의 요청을 처리한 후 응답을 보내준다.

🔨 5. 토큰 기반 인증의 장점

1️⃣ Statelessness & Scalability (무상태성 & 확장성)
  • 서버는 클라이언트에 대한 정보를 저장할 필요가 없다 → 토큰은 해독되는지만 판단한다.
  • 클라이언트는 새로운 요청을 보낼 때 마다 토큰을 헤더에 포함시키면 된다.
    - 서버를 여러 개 가지고 있다면 → 같은 토큰으로 여러 서버에 인증이 가능하다 ✌️
2️⃣ 안전하다
  • 암호화한 토큰을 사용하고, 암호화 키를 노출할 필요가 없어 안전하다.
3️⃣ 어디서나 생성 가능하다
  • 토큰을 확인하는 서버가 토큰을 만들지 않아도 된다.
  • 토큰 생성용 서버를 만들거나, 다른 회사에서 토큰 관련 작업을 맡기는 등 → 다양한 활용이 가능하다.
4️⃣ 권한 부여에 용이하다
  • 토큰의 Payload(내용물) 안에 어떤 정보에 접근 가능한 지 정할 수 있다.
    - e.g. 서비스의 사진과 연락처 사용권한만 부여
profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글