인증 & 인가

Jeongyun Heo·2021년 2월 7일
0

1. 인증이란?

식별 가능한 정보로 서비스에 등록된 유저의 신원을 입증하는 과정

인증(Authentication): 입증, 증명
유저의 신원 확인, 신분 증명, 식별하는 절차 (유저의 아이디와 비밀번호를 확인하는 절차)

로그인 하는 과정

게시물을 작성할 수 있다.
다른 사람이 작성한 게시물을 볼 수 있다.
다른 사람의 게시물을 수정할 수는 없다.

인증은 회원가입과 로그인을 말한다.

인증은 왜 필요할까?

우리 서비스를 누가 쓰는지
20대인지 30대인지, 여성인지 남성인지
30대 여성이 많이 이용하면 30대 여성을 공략

인증에 필요한 것은 무엇이 있나?

아이디, 이메일 주소, 비밀번호 등
가장 중요한 것은 비밀번호

비밀번호가 왜 중요할까?

보안때문에
비밀번호를 알면 그 사람의 개인정보에 다 접근이 가능함
개인정보보호법은 개인정보 암호화에 대해 다음과 같이 규정하고 있다.
개인정보가 암호화되지 않고 개인정보처리 시스템에 저장되거나 네트워크를 통해 전송될 경우, 노출 및 위조, 변조 등의 위험이 있으므로 암호화 등의 안전한 보호조치가 제공되어야 한다.

⭐️ '암호화'는 개인정보취급자의 실수 또는 해커의 공격 등으로 인해 개인정보가 비인가자에게 유출, 노출 되더라도 그 내용 확인을 어렵게 하는 보안기술이다.

국가에서 권고하는 상용 암호화 알고리즘을 이용해 개인정보를 암호화하도록 법적으로 요구하고 있다.

2. 비밀번호 암호화는 어떻게 이루어지는가?

로그인 절차

  1. 유저 아이디와 비밀번호 생성
  2. 유저 비밀번호를 암호화해서 DB에 저장
  3. 유저 로그인 (아이디와 비밀번호 입력)
  4. 유저가 입력한 비밀번호 암호화한 후, 암호화 돼서 DB에 저장된 비밀번호와 비교 (bcrypt.checkpw)
  5. 일치하면 로그인 성공
  6. 로그인 성공하면 access token을 클라이언트에게 전송
  7. 유저는 로그인이 성공하고부터는 access token을 첨부해서 request를 서버에 전송함으로써 매번 로그인을 하지 않아도 된다.

유저 비밀번호 암호화

백엔드에서 데이터베이스에 비밀번호를 저장할 때 암호화를 해서 복원할 수 없도록 한다.
유저의 비밀번호는 절대 그대로 DB에 저장하지 않는다.
DB가 해킹을 당하면 유저의 비밀번호도 그대로 노출 된다.
외부 해킹이 아니더라도 내부 개발자나 인력이 유저들의 비밀번호를 볼 수 있다.
유저의 비밀번호는 반드시 암호화해서 저장해야 한다.
그러므로 DB가 해킹을 당해도 비밀번호가 그대로 노출되지 않으며
내부 인력도 비밀번호를 알 수 없다.

비밀번호 암호화에는 단방향 해시 함수(one-way hash function)가 일반적으로 쓰인다.
단방향 해시 함수는 수학적인 연산을 통해 원본 메시지를 변환하여 암호화된 메시지인 다이제스트(digest)를 생성한다. 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어야 하며 이를 '단방향성'(one-way)이라고 한다.

비밀번호를 데이터베이스에 저장할 때 아무런 가공도 하지 않은 텍스트로 저장하면 보안상 매우 위험하다. 따라서 단방향 해시 함수를 지원해주는 bcrypt 라는 라이브러리를 사용하여 안전하게 저장한다. Bcrypt 라이브러리는 단순 텍스트 패스워드를 해시하기 위한 이미 완성된 구현체를 쓰게 해준다.

3. 단방향 해쉬함수 그리고 레인보우 테이블 어택

단방향 해시 함수의 취약점

'1234'를 SHA-256 함수를 사용해서 해싱하면
03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4

결과만 봐서는 당장 식별이 불가능하므로 완벽해보이나
같은 알고리즘으로 '1234'를 다시 해싱하면 항상 같은 결과가 나옴

이와 같은 허점을 이용해서 미리 해시값들을 계산해 놓은 테이블을 Rainbow table 이라고 함

Rainbow table를 판매하는 서비스도 존재함

Rainbow Table을 이용해서 해시값을 유추해주는 사이트도 존재

4. Salting과 Key Stretching 그리고 bcrypt

단방향 해시 함수의 취약점들을 보완하기 위해 Salting과 Key Stretching 사용
비밀번호와 임의로 생성한 문자열(Salt)를 합쳐서 해싱하여 이 해시값을 저장하는 방법

Salting

입력한 비밀번호와 추가적으로 임의로 생성한 문자열(Salt)를 합쳐서 해시값을 계산하여 저장하는 방법.
랜덤한 문자를 내 비밀번호 사이사이에 뿌린다.
물론 이때 비교를 위해 해시값과 소금(Salt)값을 같이 저장해야 함

여기에 해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 Salting 및 해싱을 여러 번 반복해서 원본값을 유추하기 어렵게 만드는 것이 Key Stretching

Key Stretching

단방향 해시값을 계산한 후 그 해시값을 또 해시하고~ 또 해시하고~~ 이를 반복하는 것을 말함

Salting과 Key Stretching을 구현한 해시 함수 중 가장 널리 사용되는 것이 bcrypt

bcrypt는 처음부터 비밀번호를 단방향 암호화하기 위해 만들어진 해시함수

bcrypt

Salting & Key Stretching 대표적 라이브러리
bcrypt는 앞서 말한 개념들을 실제로 적용하기 편하게 해주는 대표적인 라이브러리
다양한 언어를 지원하고 있으며, 사용이 간편하여 쉽게 적용이 가능
bcrypt는 hash결과값에 소금(Salt)값과 해시값 및 반복횟수를 같이 보관하기 때문에 비밀번호 해싱을 적용하는데 있어 DB설계를 복잡하게 할 필요가 없다

5. 인가란?

인증된 사용자에 대한 자원 접근 권한 확인

인가(Authorization): 허가, 허가증
사용자가 서버에 로그인하면 해당 사용자가 맞는지 확인하는 과정
유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가 확인하는 절차
넷플릭스 멤버십 결제한 유저인가 확인...

http의 특징 중에 stateless (저장하지 않는 성질)

서버는 사용자가 로그인 했다는 것을 어떻게 알 수 있을까?
👉 headers에 메타데이터를 보내서 확인

이 메타정보를 바로 JWT(JSON Web Token)이라고 함
메타정보: 정보들의 정보(정보들의 상위 정보)

로그인 하면 Token을 줌

발행 받은 Token과 함께 요청 보냄

6. JWT에 대해 배워봅시다.

서버는 사용자가 로그인 했다는 것을 어떻게 알 수 있을까?
👉 headers에 메타데이터를 보내서 확인

이 메타정보를 바로 JWT(JSON Web Token)이라고 함
메타정보: 정보들의 정보(정보들의 상위 정보)

로그인 하면 Token을 줌

유저가 로그인에 성공하면 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 됨

발행 받은 Token과 함께 요청(request) 보냄

JSON Web Token 구조
JWT는 3개의 파트로 구성되며 .(dot)으로 구분되는 각 파트는 다음과 같다.
헤더(header)
내용(payload)
서명(signature)

헤더(Header)

토큰의 타입과 해시알고리즘 정보가 들어간다
헤더의 내용은 BASE64 방식으로 인코딩해서 JWT의 가장 첫 부분에 기록된다.

{“alg”: “HS256”, “typ”: “JWT”}

내용(Payload)

클레임(claim)들을 포함하고 있음
내용에는 exp와 같이 만료시간을 나타내는 공개 클레임
그리고 클라이언트와 서버 간 협의하에 사용하는 비공개 클레임
위의 두 가지 요소를 조합하여 작성한 뒤 BASE64 인코딩하여 두 번째 요소로 위치

{ “user-id” : 1, “exp”: 1539517391 }

서명(Signature)

JWT가 원본 그대로라는 것을 확인할 때 사용하는 부분
시그니쳐는 BASE64URL 인코드된 header와 payload 그리고 JWT secret(별도 생성)을 헤더에 지정된 암호 알고리즘으로 암호화하여 전송한다. (복호화 가능)
프론트엔드가 JWT를 백엔드 API 서버로 전송하면 서버에서는 전송받은 JWT의 서명부분을 복호화하여 생성한 JWT가 맞는지 확인

0개의 댓글