인증과 인가

1. 인증은 무엇이고 왜 필요한가?

1-1. 인증은 무엇일까?

개인정보를 통해 본인임을 증명하는 방법이라고 쉽게 설명을 할 수 있다. 우리가 회원가입 시 휴대폰 본인인증 서비스를 이용하여 본인을 확인시켜주고 가입을 할 수 있고, 이렇게 가입한 아이디로 웹페이지에 로그인을 할 수 있는데 이러한 과정을 인증이라고 정의할 수 있다.

1-2. 인증은 왜 필요한가?

우리가 만든 서비스를 어떤 사용자가 사용하고, 어떻게 사용하고 있는지 추적을 할 수 있게 하기 위해서 인증 절차를 필요로 한다. 이를 위해 우리는 아이디(ID), 이메일(e-mail), 비밀번호(password)등을 필요로 한다. 위 수단들 중 비밀번호는 중요한 개인정보이므로 따로 관리를 해야한다.

1-3. 인증 수단(비밀번호)을 관리하는 방법

먼저, 비밀번호는 개인정보 보호법으로 개인정보의 암호화에 대해 규정이 되어있다. 이러한 법규상의 강제로 비밀번호는 암호화를 하여 관리해야 하며, 관리하는 방법은 아래와 같다.

  • 암호를 해싱하는 방법 : 이 방법은 DB(데이터베이스)에 비밀번호를 저장할 때, 개인정보(비밀번호)를 해싱(난독화)하여 복원할 수 없도록 하는 방법이다.

    (실제 활용된 예시) 우리가 가입한 사이트에서 비밀번호를 찾고자 할 때 기존의 비밀번호를 알려주지 않고 재설정하게 만드는 이유는 ? 이미 유저의 비밀번호가 해싱을 통해 관리되어 사이트에서 기존의 비밀번호를 찾을 수 없기 때문

  • SSL(Secure Sockets Layer)을 통한 네트워크 통신 방법 : 이 방법은 HTTP 통신을 할 때 단순한 텍스트 형태로 통신을 하게될 경우 발생하는 문제를 막기 위해서 HTTP 메세지 자체에 한번 더 보안을 입힌(SSL)통신을 하는 것이다. 이를 상호 소통하게 만들어 주는 것은 HTTPS이다.
    (실제 활용된 예시) HTTP만 있는 사이트를 크롬에서 열게되면 "이 사이트는 안전하지 않습니다." 라는 문구를 띄우는 것도 확인할 수 있음)

    잠깐, SSL에 대해서 알고가는 시간을 가지겠다.
    SSL(Secure Sockets Layer)은 웹사이트와 브라우저(혹은 두 서버)사이에 전송된 데이터를 암호화하여 인터넷 연결 보완을 유지하는 표준 기술로, 해커가 개인정보 및 금융정보를 포함한 전송되는 모든 정보를 열람하거나 훔치는 것을 방지해준다.

    필요한 이유는? 웹 사이트에서 전송이 이루어지는 모든 유형의 정보(결제, 로그인 패널 및 서식, 블로그 및 정보사이트) 보안을 유지해주기 때문이다.
    더 자세한 내용은 https://www.digicert.com/kr/what-is-ssl-tls-https/ 이곳을 통해 알아 볼 수 있도록 하겠다.

1-4. 인증 수단(비밀번호)을 암호화 하는 방법

  • 단방향 Hash
    - 보통 Hash함수는 자료구조에서 빠른 자료의 검색, 데이터 위변조 체크를 위해 사용되지만, 복원이 불가능한 단방향 해쉬함수는 암호학적 용도로도 사용이 된다. 하나의 input에 하나의 output만 나오며 단 방향이기 때문에 output을 통해서 input을 알 수 없다.

    예) 숫자 1 - > 2,000 / 숫자 2 -> 5,000 / 5,000 -> ??? / 2,000 -> ??? ( 단방향의 예시)

    예) '1234’를 SHA-256으로 해싱하면 03ac67132413243e15c761ee1adfa(알고리즘에 따라 암호화 한 것) ‘1234’를 다시 해싱하면, 항상 같은 결과가 도출됨(하나의 input에 하나의 output 예시)

    - 종류 : MD5(보완에 취약), SHA-1(보완에 취약), SHA-256 등

    - 단점 : 결과만 봐서는 당장 식별이 불가능하므로 완벽해보이지만 알고리즘으로 다시 해싱을 하면 같은 결과가 도출되기 때문에 '레인보우 테이블'을 이용해 해시값을 유추할 수 있어 보완에 취약하다.

  • Salting & KeyStretching
    - 단방향 Hash의 단점을 보완하기 위해 생겨난 아이디어로 사용자가 입력한 비밀번호와 임의로 생성한 문자열(Salt)를 합쳐 해싱한 결과값을 저장하는 방법이다.여기 추가적으로 해커가 패스워드를 무작위로 대입하여 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 솔팅 및 해싱을 여러번 반복해서 원본값 유추를 어렵게 만든 것이 KeyStretching 이다.

    " Salting & KeyStretching의 핵심은 암호화를 복구하는데 오랜 시간을 걸리게 하는 것! "

    예시) 로그인과정 : 프론트엔트(유저로부터 Password 받음) -> 서버로 보냄(유저로부터 받은 비밀번호에 솔팅값을 더해서 Hashing) -> DB에 입력된 비밀번호랑 맞는지 확인(Matchig)

인증 수단(비밀번호)을 암호화 하는 방법에 대한 세션 중 질문

Q1. DB에 저장될 때 Salt값은 고정이 되나요?
A . 고정된다. Hashing Process와 KeyStretching을 거쳐 암호화 한 뒤 Hash가 되고, 어떤 값이 Salting되었는지 앞에 나타내준다.(그림 속 Password Creation 참고)

Q2. Salting값의 위치는 어떻게 설정하나요?
A. 함수를 설정할 때 정할 수 있고, Salting값은 뒷쪽에 위치시키는 것이 일반적이다.

Q3. KeyStretching으로 여러번 암호화를 해두었는데, DB에는 Salting값, 원본 비밀번호가 저장되는 건가요?
A. 유저가 입력한 비빌번호로 그대로 저장되면 법의 규제에 위배되는 것이므로 유저가 입력한 값 자체에 솔팅을 하고 비밀번호를 암호화 하는것이다. 즉, 원본값은 저장될 수 없다.

Q4. 비밀번호 + Salting값으로 해시가 된 것이면 Hash는 그 둘이 암호화 된 값이고 Hash블럭 앞의 Salting블럭은 Salt값을 알기 위한 것인가요?
A. return true

Q5. Salting은 1회만 하는 것이고 Hashing을 많이 하는 것인가요?
A. Salting은 랜덤 1회만 진행하고 3~5회 정도 해싱을 한다.

1-5. bcrypt

Salting & KeyStretching의 대표적인 라이브러리로 다양한 언어를 지원하고, 사용이 간편하여 쉽게 적용할 수 있다. 또, Hash 결과값에 Salt 값과 Hash값 및 반복횟수를 같이 보관하기 때문에 DB설계를 복잡하게 할 필요가 없다.
아래의 이미지는 bycrypt를 이용하여 Hashing된 결과값의 구조이다.

2. 인가는 무엇이고 왜 필요한가?

2-1. 인가는 무엇인가?

인가는 사용자가 요청하는 요청(Request)을 실행할 수 있는 권한 여부를 확인하는 절차다.

2-2. 인가는 왜 필요한가?

인가가 필요한 이유를 간단하게 예를들자면, 넷플릭스 이용자가 넷플릭스가 아닌 왓챠에서 서비스 이용을 위해 넷플릭스에 등록된 정보로 로그인을 시도한다면 왓챠에서는 권한이 없기 때문에 실패할 것이다.

2-3. http의 특징과 토큰(Token)

http의 특징은 비연속적이고 요청(Request)과 반응(Respond)이 바로 이루어 진다는 것이다. 이처럼 사용자가 로그인을 요청하면, 바로 반응(로그인성공 또는 실패)이 나타난다. 이때, 로그인을 성공한 사용자에게는 토큰(Token)이 발급된다.

  • 토큰(Token)
    토큰은 그 자체가 메타데이터이기 때문에 HTTP의 header에 담아서 전달이 되고, 쿠키(cookie),세션(session),로컬스토리지(localstorage) 등에 저장된다.

2-4. 토큰(Token)의 구조

  • JSON Web Token의 형태 알아보기

    - 헤더(header)
    (1) 토큰의 타입과 해시알고리즘 정보가 들어간다.
    (2) 헤더의 내용은 BASE64 방식으로 인코딩해서 JWT의 가장 첫 부분에 저장된다.
    (3) 인코딩 된 상태이다.(주의사항 : 암호화 된 것은 아니기 때문에 오해하지 말 것)
    (4) 예시 : {"alg" : "hs256", "typ" : "JWT"}

    - 내용(payload)
    (1) exp와 같은 만료시간을 나타내는 공개 클레임이다.
    (2) 클라이언트와 서버간 협의하에 사용하는 비공개 클레임이다.
    (3) 위 두가지 요소를 조합하여 작성한 뒤 BASE64 인코딩하여 두번째 요소로 위치한다.
    (4) 인코딩 된 상태이다.(주의사항 : 암호화 된 것은 아니기 때문에 오해하지 말 것)
    (5) 예시 : {"user-id" : 1, "exp" : 1539517391}

    - 서명(signature)
    (1) JWT가 원본 그대로라는 것을 확인할 때 사용하는 부분이다.
    (2) 시그니처는 BASE64URL 인코드 된 헤더(hader) & 내용(payloard) 그리고 JWT secret(별도생성)을 헤더에 지정된 암호 알고리즘으로 암호화하여 전송한다.(복호화 가능)
    (3) 프론트엔드가 JWT를 백엔드 API 서버로 전송하면 서버에서는 JWT의 서명부분을 복호화하여 서버에 생성한 JWT가 맞는지 확인한다.(계약서 위변조를 막기위해 사인하는 것과 같다.)
    (4) 헤더(header)와 내용(payloard)은 BASE64 인코딩을 한 것이므로 누구나 원본을 볼 수 있으니 개인정보를 담아서는 안된다.

인가 세션 중 질문

Q1. JWT의 형태는 변경되지 않고 똑같은 형태로 로그인시 계속 유지되나요?
A . 구조 자체는 변경되지 않지만, 페이로드에 만료시간이 만료되면 그 때부터 다시 로그인을 하고 새로운 토큰을 발급한다.

profile
발전하고 싶은 프론트엔드 개발자 입니다 :)

0개의 댓글