Authentication & Authorization

Chris-Yang·2021년 10월 3일
1

ComputerScience

목록 보기
1/2
post-thumbnail

> Authentication

▶︎ 인증이란?


Authentication == identification

접근하려는 대상이 누구인가를 확인하는 절차를 말한다.

예를 들면 해외여행을 할 때 여권을 제시하거나, 교통경찰에게 면허증을 보여주는 등
신분증을 통해 내가 누구인지 상대방에게 증명해 보일 수 있다.

이와 마찬가지로 어느 웹페이지에서 회원가입 후 로그인을 하는 경우
가입할 때 작성한 아이디나 이메일, 패스워드를 입력해 인증을 받게 되어
그 웹페이지에 로그인 할 수 있게 되는 것이다.


▶︎ 인증을 하는 이유

신분증을 통한 증명을 왜 하는지 생각해보자.

여권의 경우 내가 해외여행을 할 수 있는 대상인지를 확인할 수 있고
면허증은 내가 운전을 해도 되는 대상인지 확인할 수 있다.

웹페이지에서는 대상이 우리 서비스에 가입되어있는지,
어느 서비스를 이용하는지 등의 정보를 얻을 수 있다.

▶︎ 비밀번호 관리

개인정보보호법규에는 유저들의 비밀번호 암호화가 규정되어 있다.

따라서 암호화를 통해 비밀번호가 개발자나 해커에 의한 유출이 되어도
문제가 없도록 조치해야 한다.

구체적으로 유저가 회원가입을 할 때 입력한 비밀번호를 DB에 저장 시
hashing해서 복원할 수 없도록 해야 한다.


▶︎ 단방향 해시 함수(one-way hash function)

단방향 해시 함수는 원본 메시지를 변환하여 암호화된 메시지인 
다이제스트(digest)를 생성한다.

원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만, 암호화된 메시지로는
원본 메시지를 구할 수 없어'서 단방향성(one-way) 이라고 한다.

해쉬함수로는 SHA-256 을 많이 쓴다.(MD5, SHA-1은 보안 취약)

💡 원본이 있을 때의 단방향 해시 함수 동작
1234를 SHA-256으로 해싱하면 복잡한 글자가 나오지만 같은 알고리즘으로
풀면 다시 1234가 나온다.


▶︎ 단방향 암호화의 문제와 보완책

해시 함수는 원래 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다.

따라서 공격자는 rainbow table과 같은 해시값 유추 사이트 등을 통해
매우 빨리 해킹할 대상의 digest를 비교할 수 있다.

이같은 허점을 보완하고자 salting과 keystretching을 이용해야 한다.

slating:
입력한 비밀번호 + salting으로 만들어진 임의생성 문자열을 합쳐 해싱해서
이 값을 저장하는데 이때 비교를 위해 해시값과 salt값을 같이 저장해야 한다.

key stratching:
해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해
slating / hashing을 여러번 반복, 원본값 유추하기 힘들게 만드는 것이
key stratching이다.

💡 rainbow table
해시 함수를 사용하여 변환 가능한 모든 해시 값을 저장시켜 놓은 표.
해시 함수로 저장된 비밀번호로부터 원래의 비밀번호를 추출해 내는데 사용된다.


▶︎ bcrypt

salting & key stratching 개념을 실제 적용하기 편하게 해주는 대표적 라이브러리로
python, JavaScript, java 등 다양한 언어 지원하며 사용 간편하다.

bcrypt 라이브러리를 이용해 손쉽게
비밀번호+slating(랜덤문자 생성) / 해싱 -> 수회 반복(key staratching)을 하면
일반적인 컴퓨터로 초당 수십억개의 digest를 비교할 수 있던 것을
동일한 컴퓨터에서 1초에 5번 정도만 비교 가능하게 만들 수 있다.

회원가입 ->
bcrypt를 통해 비밀번호 암호화, DB에 저장 ->
로그인 시도 ->
백엔드서버는 db에 저장된 암호화된 비밀번호와 대조 ->
인가(Authorization)여부 결정.





> Authorization

▶︎ 인가란?


Authorization == permission

접근하려는 대상이 어느정도의 권한을 가지고 있는지 확인하는 절차를 말한다.

"관계자 외 출입 금지" 라는 표식이 된 문을 본적이 있을 것이다.

병원 건물에 들어갔다 해도 우리는 모든 문을 열 수 없지만
권한이 있는 관계자는 그 출입구를 이용할 수 있다.

누구나 넷플릭스에 가입하고 로그인을 할 수 있지만 유료 서비스를
가입한 사람만 유료서비스에 접근할 권한을 갖게 되어
어떠한 동영상이든 볼 수 있게 된다.


▶︎ 인가를 하는 이유?

인가는 위에서 말했던 것 처럼 특정 대상이 어떤 서비스에 접근할 수 있는지
식별하고 통제할 수단으로써 역할을 한다.

만약 누구나 웹페이지의 admin 페이지에 접근할 수 있다면
심각한 정보유출이나 조작 등의 큰 피해로 이어질 것이다.

또한 stateless한 HTTP의 특징은 로그인 상태 유지를 어렵게 만드는데
유저는 로그인 성공시 백엔드서버로부터 받은 증명서를 통신할때마다 발송하며
이를 통해 stateless(비연속성)문제를 해결할 수도 있다.


▶︎ Cookie/Session, JWT(JSON Web Token)

인가에는 token, cookie/session이 주로 사용된다.

유저가 계정정보를 HTTP header에 넣어 백엔드서버로 요청을 보내는 경우
보안문제가 발생하기 때문에 다음과 같은 방법으로 인가를 실시한다.


cookie/session:
유저가 로그인에 성공 하면 백엔드서버의 세션 저장소에 사용자 정보를 저장,
열쇠로 사용할 수 있는 세션ID 를 만들고 HTTP header에 실어 유저에게 보낸다.

유저는 세션ID를 포함하는 cookie를 저장하고 인증이 필요한 경우 request로
해당 cookie를 서버에 보낸다.

서버에서는 쿠키를 받아 세션 저장소에서 확인 한 후 일치하는 정보를 가져온다.
인증이 완료되면 백엔드서버는 그 유저에게 데이터를 보내준다.


token:
access token을 생성하는 방법은 여러가지가 있는데, 그 중 가장 널리 사용되는
기술중 하나가 바로 JWT(JSON Web Tokens)다.

JWT는 헤더(header), 내용(payload), 서명(signature) 3개의 구조로 되어 있다.
header에는 암호화할 방식과 타입({"alg":"HS256", "typ":"JWT"},
payload에는 서버에 보낼 데이터와 유효기간({"user_id":1, "exp":만료기간),
signature에는 Base64로 인코딩된 Header, Payload, Secret key(JWT secret)를
지정된 암호 알고리즘으로 암호화하여 header에 전송한다.

유저가 로그인에 성공하면 서버에서는 계정 정보를 읽어 사용자를 확인 후, 사용자의
고유ID값을 부여한 후 기타 정보와 함께 payload에 집어넣는다.

JWT token의 유효기간을 설정하고 암호화할 secret key를 이용해
access token을 발급한다.

유저는 access token 을 받아 저장 후, 인증이 필요한 요청마다 토큰을 header에
실어 보낸다.

백엔드서버에서는 해당 토큰의 verify signature를 secret key로 복호화한 후,
조작 여부, 유효기간을 확인한다.

검증완료시 payload를 디코딩 하여 사용자 ID와 일치하는 데이터를 가져온다.


session/cookie, JWT 차이점
session/cookie는 세션 저장소에 로그인된 유저 정보를 보관하며
따라서 유저정보를 저장할 별도의 세션 DB가 필요하고
요청이 들어올 때마다 세션ID와 일치하는 유저를 찾아야 한다.

JWT의 경우 토큰 안에 인증하는데 필요한 유저의 정보들이 담겨있다.
유저정보를 저장할 별도의 DB가 필요하지 않는 대신 정보에 사인하고 전달한다.





> 참고

▶︎ web

🥕 위키백과: https://ko.wikipedia.org/wiki/Bcrypt

🥕 노마드코더: https://youtu.be/tosLBcAX1vk

🥕 0985개발로그: https://tofusand-dev.tistory.com/89

▶︎ 서적

🥕 http 완벽가이드

profile
sharing all the world

0개의 댓글