Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

옥수수, 기록

[Backend 인증/보안] Token과 OAuth 본문

카테고리 없음

[Backend 인증/보안] Token과 OAuth

ok-soosoo 2023. 1. 9. 21:37

해싱(Hashing)

가장 많이 쓰이는 암호화 방식중 하나

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

해싱의 특징

  • 항상 같은 길이의 문자열 리턴
  • 서로 다른 문자열에 동일한 해시 함수를 사용하면 반드시 다른 결과값이 나옴
  • 동일한 문자열에 동일한 해시 함수를 사용하면 항상 같은 결과값이 나옴

해시 함수중 하나인 SHA1에 특정 입력 값을 넣었을 때 어떤 결과가 리턴되는지에 대한 예

비밀번호 해시 함수(SHA1) 리턴 값

비밀번호 해시 함수(SHA1) 리턴값
‘password’ ‘5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8’
‘Password’ ‘8BE3C943B1609FFFBFC51AAD666D0A04ADF83C9D’
‘kimcoding’ ‘61D17C8312E8BC24D126BE182BC674704F954C5A’

레인보우 테이블과 솔트

항상 같은 결과값이 나온다는 특성을 이용, 해시 함수를 거치기 이전의 값을 알아낼 수 있도록 기록해놓은 표인 레인보우 테이블이 존재

레인보우 테이블에 기록된 값의 경우 유출되었을 때 해싱을 했더라도 해싱 이전 값을 알아낼 수 있으므로 보안상 위협이 될 수 있음

이 때 활용할 수 있는 것이 솔트(Salt)

소금을 치듯 해싱 이전 값에 임의의 값을 더해 데이터가 유출 되더라도 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법

비밀번호 + 솔트  해시 함수(SHA1) 리턴 값
‘password’ + ‘salt’ ‘C88E9C67041A74E0357BEFDFF93F87DDE0904214’
‘Password’ + ‘salt’ ‘38A8FDE622C0CF723934BA7138A72BEACCFC69D4’
‘kimcoding’ + ‘salt’ ‘8607976121653D418DDA5F6379EB0324CA8618E6’

솔트를 사용하면 솔트가 함께 유출 된 것이 아닌이상 암호화 이전의 값을 알아내기란 불가능에 가깝다.

해싱의 목적

복호화가 불가능한 암호화 방식을 사용하는 이유는 데이터의 내용을 사용하는 것이 아니라 동일한 값의 데이터를 사용하고 있는지 여부만 확인하는 것이 목적

ex) 사이트 회원가입시 입력한 비밀번호는 해싱되어 데이터베이스에 저장

이후 로그인 때 마다 비밀번호를 해싱해 데이터베이스에 저장되어 있는 해싱값과 비교

Token

토큰기반 인증(Token-based Authentication)

클라이언트에 인증 정보 보관하기

오락실 게임에서 사용하는 토큰, 행사 입장을 위해 주최측에서 나눠주는 티켓(토큰), 놀이공원 입장티켓(토큰) 이런 개념에서 착안해 클라이언트에서 인증 정보를 보관하는 방법으로 토큰 기반 인증이 고안됨

클라이언트는 XSS, CSRF공격에 노출될 위험이 있으니 토큰을 클라이언트에 보관하면 안된다라고 생각할 수 있지만 토큰은 유저 정보를 암호화하기 때문에 클라이언트에 담을 수 있음

JWT의 종류

보통 두 가지 종류의 토큰을 이용해 인증을 구현

  • 액세스 토큰(Access Token)
    • 보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용
  • 리프레시 토큰(Refresh Token)

클라이언트가 처음 인증을 받게 될 때(로그인 시) 액세스 토큰, 리프레시 토큰 두 가지를 다 받음

실제로 권한을 얻는 데 사용하는 토큰은 액세스 토큰

권한을 부여 받는데에는 엑세스 토큰만 가지고 있으면 되지만 액세스 토큰을 해커가 탈취했다면 토큰 소유자인척 서버에 여러가지 요청을 보낼 수 있음

그래서 액세스 토큰에는 비교적 짧은 유효기간을 부여 → 액세스 토큰 만료시 리프레시 토큰을 사용해 새로운 액세스 토큰을 발급 → 🚨유저는 다시 로그인 할 필요가 없음

 

🚨 if 리프레시 토큰 탈취시

리프레시 토큰은 액세스 토큰보다 상대적으로 유효기간이 길기때문에 탈취시 큰 문제

→ 유저의 편의보다 정보를 지키는 것이 더 중요한 웹 사이트들(은행)은 리프레시 토큰 사용 X

JWT 구조

1 Header

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

어떤 종류의 토큰인지(지금은 JWT), 어떤 알고리즘으로 시그니처를 sign(암호화)할지 적혀있다.

JSON Web Token 이라는 이름에 걸맞게 JSON 형태로 정보가 담겨있다.

이 JSON 객체를 base64방식으로 인코딩하면 Header 완성

2 Payload

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

단어 그대로 서버에서 활용할 수 있는 유저의 정보가 담겨 있다.

어떤 정보에 접근 가능한지에 대한 권한 또는 유저의 이름과 같은 개인정보 등을 담을 수 있다.

페이로드도 디코딩이 쉬운 base64방식으로 인코딩하기 때문에 너무 민감한 정보는 담지 않는 것이 좋다.

3 Signature

// HMAC SHA256알고리즘(암호화 방식 중 하나)을 사용할 경우의 Signature 생성

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

base64로 인코딩 된 헤더와 페이로드가 완성되었다면 signature는 이것들을 서버의 비밀 키(암호화에 추가할 salt)와 헤더에서 지정한 알고리즘을 사용하여 해싱한다.

secret의 한글자만 달라도 암호는 크게 바뀌게 된다.

JWT 사용 예시

JWT는 권한 부여에 굉장히 유용하다.

만약 Spark라는 앱이 Gmail과 연동되어 이메일을 읽어와야 한다고 가정

1 Gmail 인증 서버에 로그인정보를 제공

2 성공적으로 인증시 JWT를 발급

3 Spark앱은 JWT를 사용해 해당 유저의 Gmail이메일을 읽거나 사용 가능

토큰 기반 인증 절차

1 클라이언트가 서버에 아이디/ 비밀번호를 담아 로그인 요청을 보냄

2 아이디 비밀번호가 일치하는지 확인, 클라이언트에게 보낼 암호화된 토큰 생성

  • access/refresh 토큰을 모두 생성
  • 토큰에 담길 정보(payload)는 유저를 식별할 정보, 권한이 부여된 카테고리(사진, 연락처 기타 등등 )이 될 수 있다.
  • 두 종류의 토큰이 같은 정보를 담을 필요는 없다.

3 서버가 토큰을 클라이언트에게 보내주면 클라이언트는 토큰을 저장

  • 저장하는 위치는 Local Storage, Session Storage, Cookie 등 다양

4 클라이언트가 HTTP 헤더(Authnorization 헤더) 또는 쿠키에 토큰을 담아 보냄

쿠키에는 리프레시 토큰을 헤더 또는 바디에는 액세스 토큰을 담는 등 다양한 방법으로 구현할 수 있음

  • Authorization 헤더를 사용한다면 Bearer Authentication을 이용

참조링크

https://learning.postman.com/docs/sending-requests/authorization/#bearer-token

https://tools.ietf.org/html/rfc6750

5 서버는 토큰을 해독, “아 우리가 발급해준 토큰이 맞다”라고 판단이 될 경우, 클라이언트의 요청을 처리한 후 응답을 보내준다.

토큰기반 인증의 장점

1 Statelessness & Scalability (무상태성 & 확장성)

  • 서버는 클라이언트에 대한 정보를 저장할 필요 X (토큰이 해독되는지만 판단)
  • 클라이언트는 새로운 요청을 보낼 때 마다 토큰을 헤더에 포함시키면 됨
    • 서버를 여러개 가지고 있는 서비스라면 같은 토큰으로 여러 서버에서 인증가능 → 오히려 좋아 → 세션방식이었다면 모든 서버가 해당 유저정보를 공유했어야 함

2 안전

  • 암호화한 토큰을 사용, 암호화 키를 노출할 필요가 없기 때문에 안전

3 어디서나 생성 가능

  • 토큰을 확인하는 서버가 토큰을 만들지 않아도 됨
  • 토큰 생성용 서버를 만들거나 다른 회사에서 토큰 관련 작업을 맡기는 것 등 다양한 활용 가능

4 권한 부여에 용이

  • 토큰의 Payload(내용물) 안에 어떤 정보에 접근 가능할 지 정할 수 있음
    • e.g. 서비스의 사진과 연락처 사용 권한만 부여

OAuth

OAuth?

인증을 중개해주는 매커니즘으로 보안된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공하는 프로세스를 단순화하는 프로토콜 → 이미 사용자 정보를 가지고 있는 웹 서비스(Github, Google, Facebook) 에서 사용자의 인증을 대신해주고 → 접근 권한에 대한 토큰 발급 → 이를 이용 서버에서 인증 가능

OAuth의 채택 증가

유저, 개발자를 막론하고 사이트 회원가입보다 소셜 간편 로그인의 선호도가 증가하고 있는 추세

뭐가 좋아서 쓸까?

유저 : 사이트마다 회원가입을 하지 않아 아이디,비밀번호를 따로 관리하지 않아도 됨

사이트개발자 : 신규가입, 회원 관리를 신경쓰지 않아도 됨

추가로 검증되지 않은 App에서 OAtuh를 통해 로그인을 한다면 유저의 민감정보가 노출될 일 X

인증 권한에 대한 허가를 미리 유저에게 구함

OAuth에서 꼭 알아야 하는 용어

  • Resource Owner : 사용자이며 정보제공자
  • Client : Resource Owner를 대신하여 보호된 리소스에 액세스하는 애플리케이션
  • Local Server : Client의 요청을 수락하고 응답할 수 있는 서버
  • Authorization Server : 인증을 담당하고 있는 서버 → Access Token을 발급해줌
  • Authorization Grant : Client가 Access Token을 얻는 방법
    • Authorization Code Grant
    • Refresh Token Grant Type
  • Authorization Code : Authorization Grant의 한 타입 → Access Token을 발급받기 위한 Code
  • Access Token : 보호된 리소스에 액세스하는 데 사용되는 인증 토큰 → 이 토큰으로 Resource Server에 접근할 수 있음
  • Refresh Token : 발급받은 Access Token이 만료될 시 Refresh Token을 통해 새로운 Access Token을 발급받을 수 있음

OAuth 인증 흐름

Authorization Code Grant Type

Authorization Code를 받아 Authorization Code를 통해 Access Token을 받는 방식

Access Token이 사용자나 브라우저에 표시되지 않는다는 것을 의미하므로 Access Token이 다른 사람에게 누출될 위험 감소

Refresh Token Grant Type

Authorization Code Grant Type으로 Access Token을 발급받은 후 Access Token이 만료된 경우 Refresh Token을 활용해 새로운 Access Token으로 교환하는데 사용

사용자와의 추가 상호 작용 없이 계속 유효한 액세스 토큰을 가질 수 있음

Comments