[Backend] 해싱(hashing)과 토큰(token)

rsuubinn·2023년 3월 8일
0

backend

목록 보기
2/2

해싱(hashing)

가장 많이 쓰이는 암호화 방식 중 하나 이다.
복호화가 가능한 다른 암호화 방식들과 달리, 해싱은 암호화만 가능하다.

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

레인보우 테이블과 솔트(salt)

항상 같은 결과값이 나온다는 특성을 이용해 해시 함수를 거치기 이전의 값을 알아낼 수 있도록 기록해놓은 표인 레인보우 테이블이 존재한다.
레인보우 테이블에 기록된 값의 경우에는 유출이 되었을 때 해싱을 했더라도 해싱 이전 값을 알아낼 수 있기 때문에 보안상 위협이 될 수 있다.

이 때 활용할 수 있는 것이 솔트(salt) 이다.
솔트는 소금이라는 뜻으로, 말 그대로 소금을 치듯 해싱 이전 값에 임의의 값을 더해 데이터가 유출 되더라도 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법이다.

솔트를 사용하게 되면 해싱 값이 유출되더라도, 솔트가 함께 유출된 것이 아니라면 암호화 이전의 값을 알아내는 것은 불가능에 가깝다.

해싱의 목적

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

사이트 관리자는 사용자의 비밀번호를 알고 있을 필요가 없다.
오히려 사용자의 비밀번호를 알고 있다면, 이를 얼마든지 악용할 수 있기 때문에 심각한 문제가 생길 수도 있다.
그래서 보통 비밀번호를 데이터베이스에 저장할 때, 복호화가 불가능하도록 해싱하여 저장하게 된다.
해싱은 복호화가 불가능하므로 사이트 관리자도 정확한 비밀번호를 알 수 없다.

서버 측에서는 해싱한 값끼리 비교해서 일치하는지 확인한다.
꼭 정확한 값을 몰라도, 해싱한 값이 일치하면 정확한 비밀번호를 입력했다는 뜻이 되기 때문에 해싱 값으로만 로그인 요청을 처리하는데에도 전혀 문제가 없다.

📍 해싱은 민감한 데이터를 다루어야 하는 상황에서 데이터 유출의 위험성은 줄이면서 데이터의 유효성을 검증하기 위해 사용되는 단방향 암호화 방식이다.

토큰(token)

사용자 인증 정보(Authentication)와 권한 정보(Authorization)를 포함한 정보를 담은 암호화된 문자열


1. 사용자가 인증 정보를 담아 서버에 로그인 요청을 보낸다.
2. 서버는 데이터 베이스에 저장된 사용자의 인증 정보를 확인한다.
3. 인증에 성공했다면 해당 사용자의 인증 및 권한 정보를 서버의 비밀 키와 함께 토큰으로 암호화한다.
4. 생성된 토큰을 클라이언트로 전달한다.

  • HTTP 상에서 인증 토큰을 보내기 위해 사용하는 헤더인 Authorization 헤더를 사용하거나, 쿠키로 전달하는 등의 방법을 사용한다.
  1. 클라이언트는 전달받은 토큰을 저장한다.
  • 저장하는 위치는 Local Storage, Session Storage, Cookie 등 다양하다.
  1. 클라이언트가 서버로 리소스를 요청할 때 토큰을 함께 전달한다.
  • 토큰을 보낼 때에도 Authorization 헤더를 사용하거나 쿠키로 전달할 수 있다.
  1. 서버는 전달받은 토큰을 서버의 비밀 키를 통해 검증한다. 이를 통해 토큰이 위조되었는지 혹은 토큰의 유효 기간이 지나지 않았는지 등을 확인할 수 있다.
  2. 토큰이 유효하다면 클라이언트의 요청에 대한 응답 데이터를 전송한다.

토큰기반 인증 방식의 장점

클라이언트가 유저 인증정보를 저장한다.

무상태성

서버에서 유저의 상태를 관리하지 않음
서버는 토큰의 유효성만 검증

확장성

하나의 토큰으로 다수의 서버에 인증 가능

어디서나 토큰 생성 가능

토큰 생성만을 담당하는 인증용 서버를 만들 수 있음
여러 앱을 하나의 토큰으로 인증하는 등 다양한 활용 가능

권한 부여에 용이

사용자의 인증 정보뿐만 아니라 권한 정보도 담아 암호화 가능

토큰기반 인증의 한계

무상태성

제3자가 토큰을 탈취하는 경우 서버가 해당 토큰을 강제로 만료시킬 수 없음
따라서 토큰이 만료될 때 까지 사용자로 가장해 계속해서 요청을 보낼 수 있음

유효 기간

발급된 토큰의 값 수정이나 강제 만료가 불가능하기 때문에 토큰의 유효 기간을 짧게 설정함
사용자는 토큰 만료 시 재로그인을 진행해야하므로 사용자 경험이 떨어짐

토큰의 크기

페이로드에 담는 데이터가 많아질수록 토큰의 크기도 커짐
따라서 네트워크 전송 시 비용이 커질 우려가 있음

JWT(JSON Web Token)

: 데이터 전송에 사용하는 토큰 기반 인증 기술로 JSON 형식 으로 저장한 정보(Payload)를 암호화(서명)하여 전송

1. Header

Header에는 마치 HTTP의 헤더처럼 해당 토큰 자체를 설명하는 데이터가 담겨있다.
토큰의 종류, 그리고 시그니처를 만들 때 사용할 알고리즘을 JSON 형태로 작성한다.

{
  "alg": "HS256",
  "typ": "JWT"
}
  • 참고로 base64 방식은 원한다면 얼마든지 디코딩할 수 있는 인코딩 방식이다. 따라서 비밀번호와 같이 노출되어서는 안되는 민감한 정보를 담지 않도록 해야한다.

2. Payload

Payload는 HTTP의 페이로드와 마찬가지로 전달하려는 내용물을 담고 있는 부분이다.
어던 정보에 접근 가능한지에 대한 권한, 유저의 이름과 같은 개인정보, 토큰의 발급 시간 및 만료 시간 등의 정보들을 JSON 형태로 담는다.

{
  "sub": "someInformation",
  "name": "subin",
  "iat": 15162391
}

이 JSON 객체를 base64로 인코딩하면 JWT의 두번째 부분인 Payload가 완성된다.

3. Signature

Signature는 토큰의 무결성을 확인할 수 있는 부분이다.
Header와 Payload가 완성되었다면 Signature는 이를 서버의 비밀키(암호화에 추가할 salt)와 Header에서 지정한 알고리즘을 사용하여 해싱한다.

액세스 토큰(Access Token)

사용자가 서버 리소스에 접근할 수 있도록 접근 권한을 제공하는 토큰
보안을 위해 만료 주기가 짧게 설정되어 있음

리프레시 토큰(Refresh Token)

토큰의 짧은 만료 주기로 인해 발생되는 사용자 경험 하락을 막기 위해 고안된 토큰
기존에 발급받은 액세스 토큰이 만료됐을 때 새로운 액세스 토큰을 얻기 위해 사용함

세션토큰
인증 상태를 저장하는 곳서버클라이언트
장점서버에서 인증 상태 관리 가능서버의 무상태성으로 인한 확장성
한계서버 간 세션 데이터 공유 혹은 Sticky Session 필요서버에서 인증 상태 관리 불가(e.g. 강제 로그아웃 불가
profile
@rsuubinn

0개의 댓글