인증과 인가

건강전도사·2022년 3월 21일
0

series_of_gasoline

목록 보기
7/7

1. 왜 인증이 필요한가

  • 인증 : 올바른 유저인지 확인하는 것
  • 인가 : 유저별 권한을 부여하는 것
  • 유저의 이력을 추적하기 위해서

인증에 필요한것은?

  • ID/Email : 외부에 노출이 된 개인정보
  • Password : 노출안된 정보. 가장 중요하다

1)비밀번호 관리하기

  • 상용 암호화 알고리즘으로 법적으로 암호화하도록 되어있다.(회원가입하여 DB에 저장될 때 암호화 진행)

    -통신시 개인정보 주고받을 때 SSL 적용하여 암호화(HTTPS)
    -http를 하나의 레이어로 감싸, 외부에서 원본을 볼 수 없게 하는 것

2)단방향 해쉬함수

  • 암호화는 가능하지만, 복호화는 불가능
  • SHA-256이 대표적
  • 결과만 봐서는 당장 식별이 불가능하나 두 가지 단점 존재.

    (문제1)메시지가 같으면 다이제스트도 동일하므로, 다이제스트 하나가 털리면 동일한 다이제스트를 사용하는 다른 사용자의 패스워드도 털려버림

    (문제2)Rainbow Attack에 취약
    ※RainbowTable에 미리 해시해둔 패스워드를 쌓아놓고 모든 값을 대입해서 로그인 시도하는 것

3)Salting & Key Stretching

  • SHA-256에서의 허점 보완하기 위해 나옴

    Rainbow Attack
    Rainbow Ta해커가 Rainbow테이블 활용해서 무작위대입으로 해시값 계산하는데 필요한 시간을 대폭 늘리기 위해,

  • 입력한 비밀번호와 임의로 생성한 문자열(salt)을 합쳐서 해싱한 후 해시값을 저장.
  • Salting: 해시값과 Salt값을 함께 저장해준다(Salt는 128bit 정도는 되어야 안전하다.)
  • Key Stretching : Salting &해싱을 여러번 반복해서 Rainbow Attack에 소요되는 시간을 늘려 원본값 유추하기 어렵게 만들기위함(Key Stretching)

    일정길이로 해싱된 값에 salt를 붙이고 해싱하고, 그 값에 salt를 또 붙여서 해싱하는 동작을 여러번 반복함.
    3개월지나면 비밀번호를 바꿔야하는 이유가 여기에 있다.

4)bcrypt

  • Salting & Key Stretching의 대표적인 라이브러리
  • DB에 Salt 컬럼을 따로 설계하지않아도 저장없이 알아서 해줌.

2. 인가는 무엇인가?

  • 해당 유저가 request에 해당하는 권한이 있는지 확인하는 절차

    HTTP는 stateless한 특성을 지니므로, 각 통신의 상태는 저장되지 않는다.
    그러나 매번 새 페이지를 요청할때마다 로그인을 해야 한다면 사용이 불가능할 것이다.

상기 문제 해결위해 Session과 Token 등장

1)Session과 Token

  • 유저의 로그인 시도 후 서버에서 일치하는 값을 찾은 후 유저에게 Session 또는 Token을 발급함.

  • 브라우저는 request마다 해당 Session 또는 Token을 함께 보냄

  • Session은 서버에서 관리, Token은 웹브라우저에 저장되므로 민감정보를 담지 않고 유효기간 짧게 설정함.
    짧은 유효기간으로 인한 불편함은 Refresh Token 발행하여 유효기간 연장하고 좀 더 안전한곳에 저장하도록 하여 해소.

  • Session은 오늘날 분산된 서버형태에서는 사용하기 어렵고 서버부하 많이 걸림. 확장성에 유연하지 못함. 이에 주로 Token을 사용함

2) JASON web Token

  • 서버는 사용자가 로그인했을 경우 headers에 메타데이터를 보내 확인하는데, 해당 메타정보를 JWT(Jason Web Token)이라고 함.

    토큰이 우리서버에서 발급한게 맞는지 확인하기 위한 것.
    개인정보를 담긴 담아야하는데, 우리 DB에서만 인식할 수 있는 값을 넣어준다

  • 헤더 인코딩(암호화 아님)

    • 토큰타입과 해시알고리즘정보를 BASE64로 인코딩
    • 인코딩은 암호화는 아님. 단 개인정보를 노출하지 않기
      ex) {"alg":"HS256", "typ":"JWT"}
  • 내용(payload) 인코딩(암호화 아님)

    • Registered Claim : 만료시간 나타내는 exp 등 미리 정의된 집합
    • Public Claim : 공개용 정보전달을 목적으로 함
    • Private Claim : 클라이언트-서버간 협의하 사용
    • 위의 세 가지 요소를 조합하여 작성후 BASE64인코딩함
      ex) {"user-id" : 1, "exp":1539517391}
  • 서명(signature) 암호화됨

    • BASE64로 인코딩된 headerplayloadJWT secret을 헤더에 지정된 양방향 암호 알고리즘으로 함호화하여 전송
    • 프론트에서 전달받은 JWT의 서명부분을 백엔드 API에서 복호화 한 후, 서버에서 생성한 JWT가 맞는지 진본여부 확인

다른 읽어볼 자료

profile
실수는 삶과 정신의 여백입니다. 여백이 많은 츄러블슈팅 맛집

0개의 댓글