인증(Authentication) & 인가(Authorization)

camille·2022년 5월 19일
0
post-thumbnail

📕 인증은 왜 필요한가?

  • 우리 서비스를 누가 쓰며 어떻게 사용하고 있는지, 추적이 가능하도록 하기 위해서 필요하다.
  • 인증이 필요한 것들은 id, email, pw 등과 같은 것들이 있다.
  • 그중에서도 가장 중요한 것은 password라고 할 수 있다.

📝개인 정보 보호법은 개인정보의 암호화에 대해서 다음과 같이 규정하고 있다.
: 비밀번호, 바이오정보, 주민등록번호 등과 같은 주요 개인정보가 암호화 되지 않고, 개인정보 처리시스템에 저장되거나 네트워크를 통해서 전송 될 경우, 노출 및 위ㆍ변조 등의 위험이 있으므로 암호화 등의 안전한 보호치가 제공되어야 한다.
"암호화"는 개인정보 취급자의 실수 또는 해커의 공격으로 등으로 인해 개인정보가 비인가자에게 유ㆍ노출 되더라도 그 내용 확인을 어렵게 하는 보안기술이다. 즉, 시스템이 인터넷에서 네트워크에 위치하는 경우나 예외적인 개인정보 항목을 다루는 경우를 제외하고 국가에서 권고하는 상용 암호화 알고리즘을 이용해 개인정보를 암호화하도록 법적으로 요구하고 있습니다.

비밀번호는 어떻게 관리해야 하는가?

  • Database에 저장 시 개인 정보를 해싱하여 복원할 수 없도록 한다.

    데이터 베이스 안에 id pk키가 있고 각각의 칼럼들이 있는데, 암호화를 하면 저장이 될 때 암호화 해서 오른쪽 처럼 저장이 되는 것을 볼 수 있다. 암호화 하지 않고 저장을 하면, 비밀번호가 다들어 날 수 있는 우려가 있기 때문에 이러한 방식으로 설계가 되어있다.

동신시 개인정보를 주고 받을 때, SSL을 적용하여 암호화 https 보안을 제공해주는 단체가 있는데, 받는 사람과 보내는 사람만 해독할 수 있는 기능을 제공한다. 개인정보를 해싱 하여 복원 할 수 없도록 한다.

📕 암호화는 어떻게 할까요?

📌 단방향 해쉬라는 것은 무엇일까?

  • 본래 해쉬(hash)함수는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해서 쓰이지만, 복원이 불가능한 단방향 해쉬함수는 암호화적 용도로 사용한다.
  • (MDS, SHA-1)(둘은 보안취약), SHA-256등이 있다.
  • '1234'를 SHA0256 해싱하면 다음과 같다.
    :03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
  • 결과만 봐서는 당장 식별이 불가능 하므로 완벽해 보인다.
  • 하지만 같은 알고리즘으로 '1234'를 다시 해싱하면 항상 같은 결과가 도출된다.
  • 즉 복원이 불가능한 한쪽으로는 암호화가 되는데 다른 한쪽에서는 암호화가 안되는 해쉬로 암호화를 진행한다.
  • 이와같은 허점을 이용해서 가능한 경우의 수를 모두 해시값으로 만들어서 판매하는 서비스인 레인보우 테이블이라는 사이트도 존재한다.List of Rainbow Tables
  • 이같은 허점을 보완하고자 salting과 Key Stretching이라는 아이디어가 생겨났는데, 비밀번호와 임의로 생성한 문자열(Salt)를 합쳐서 해싱하여 이 해시값을 저장하는 방법이다.

암호는 테이블 구조로 유추할 수 있기 때문에 암호라는 것은 백퍼센트로 못찾는 것은 아니다.

📕 SALTING & KeyStrtching?

있는 그대로 소금치고 늘린다고 생각하면 쉽다.

  • 단순 해쉬값이 해킹에 쉽게 노출되기 때문에 Salting이라는 아이디어가 생겨났다.
  • 입력한 비밀번호와 임의로 생성한 문자열(Salt)를 합쳐 해싱해서 이 해시 값을 저장하는 방법이다.
  • 물론 이때 비교를 위해 해시 값과 소금(Salt)값을 같이 저장해야한다.
  • 여기에 해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 Salting 및 해싱을 여러번 반복해서 원본 값을 유추하기 어렵게 만드는 것이 (Key Stretching)키 스트렛칭이다.
  • 회원가입을 진행할 때 솔트값을 붙여서 진행하는데, 만약 솔팅을 하면 나오는 값 + 솔트 = 암호화 된다.

📕 bcrypt

📌 Salting & Key Stretching 대표적 라이브러리

  • bcrypt는 앞서 말한 개념들을 실제로 적용하기 편하게 해주는 대표적인 라이브러리이다.
  • 다양한 언어를 지원하고 있으며, 사용이 간편하여 쉽게 적용이 가능하다.
  • bcrypt는 hash결과값에 소금값과 해시값 및 반복횟수를 같이 보관하기 때문에 비밀번호 해싱을 적용하는데 있어 DB설계를 복잡하게 할 필요가 없다.
  • bcrypt를 통해 해싱된 결과 값(Digest)의 구조는 아래와 같다.
  • 데이터 베이스에 패스워드 값만 저장하는 것 뿐 아니라 솔트값도 같이 저장해서 비교를 같이 한다.

📕 인가는 무엇일까?

해당 유저가 요청하는 해당 권한이 있는 지 확인하는 절차이다.
ex1) 쿠팡이라는 배송서비스를 이용하는데, 주문하기를 비로그인 상태에서 하면, 로그인 하라고 알림이 나타나는 것 -> 권한에 대한 허가가 필요하다.
ex2) 게시글에 좋아요를 누르면 -> 누가 눌렀는지 알아야 하기 때문에 권한 허가가 필요하다.

위 두가지 과정이 인가라고 생각 할 수 있다.

⭐⭐Stateless한 성질⭐⭐

📕 무상태 = Stateless
클라이언트와 서버 관계에서 서버가 클라이언트의 상태를 보존하지 않는 것을 의미한다.
Stateless 구조에서 server는 단순히 요청이 오면 응답을 보내는 역할만 수행하고, 세션관리는 client에게 책임이 있다. 이러한 stateless구조는 client와의 세션 정보를 기억할 필요가 없으므로, 이러한 정보를 서버에 저장하지 않는다. 하지만 필요에 따라서 외부 DB에 저장하여 관리 할 수 있다.

  • 웹서버 통신 (http)특성상 사용자(브라우저)의 이전상태 client(쿠키) or Server(세션) 정보를 기록하지 않는 접속이란 의미이다.
  • 브라우저가 데이터를 전송할 때마다 연결하고 바로 끊어버리는 방식이다.
  • 장점 : 서버의 확장성이 높기 때문에 대량의 트래픽이 발생 해도 대처를 수월하게 할 수 있다.
  • 단점 : 클라이언트의 요청에 상대적으로 Stateful보다 더 많은 데이터가 소모된다.(매번 요청할 때마다 자신의 부가정보를 줘야하기 때문에)
  • 대표적인 Stateless 프로토콜은 UDP와 HTTP가 있다.

📕 Stateless 통신의 예시

  • 텀블러을 판매하는 서버 A
  • 대체가 가능한 서버 B, C
  • 텀블러를 사려는 client D

👵D : 텀블러를 구매하려 합니다.
👩‍A : 텀블러 커스텀을 골라주세요.(server는 아무것도 기억하지 않는다.)

👵D : 텀블러를 구매하려고 합니다. 뚜껑은 하얀색, 바디는 보라색, 손잡이는 분홍색인 것으로 주세요.
🧑‍B : 배송은 어디로 해드릴까요?(서버는 아무것도 기억하지 않는다.)

👵D: 텀블러를 사려합니다. 뚜껑은 하얀색, 바디는 보라색, 손잡이는 분홍색인 것으로 주세요. 배송은 회사로 해주세요.
👴C: 결제는 무엇으로 도와드릴까요? (서버는 아무것도 기억하지 않는다.)

👵D: 텀블러를 사려합니다. 뚜껑은 하얀색, 바디는 보라색, 손잡이는 분홍색인 것으로 주세요. 배송은 회사로 해주세요.결제는 현금으로할깨요.
👴C: 결제 완료 되었습니다.(서버는 들어온 요청을 처리한다.)

여기서 클라이언트의 요청(상태)을 유지하지 않는 서버라는 점이 핵심이라고 할 수있다. 무상태는 기존의 서버가 혼잡해져서 새로운 서버를 가져다 놓아도 기존의 비즈니스 로직을 그대로 구현하고 이다면, 이전의 사용자 요청이 어떤지에 관계없이 계속일을 처리 할 수 있다. 하지만 클라이언트가 하고자하는 최종 목적을 위해 지나가는 과정마다 점점 전달해야하는 내용이 많아진다는 것이다. HTTP는 이 무상태를 특징으로 기본적으로 가지고 있다.
특별한 일이 없다면 무상태를 지향해야하며 정말필요한 경우에만 상태를 유지해야한다.

📕 인가는 무엇일까?

인가 Authorization

  • 서버는 사용자가 로그인 했을 경우, 로그인 했다는 것을 어떻게 알까?
    : 바로 header에 메타데이터를 보내서 확인한다.
  • 이 메타 정보를 바로 JSON Web Token 일명 'JWT'라고 한다.

    ** 👩‍🏫 HTTP 특정예시**

    • 요청1 : zoom 로그인
    • 응답1 : 로그인 200 OK!
    • 요청2 : meeting 접속
    • 응답2 : meeting 접속 OK!

요청 1의 응답 1에서 200 OK와 Token 발행한다.
요청 2는 발행 받은 Token과 함께 요청 보낸다.

이 무거운 문제를 해결해야 하는데, 이 문제를 해결하기 위해서 리퀘스트 헤더라는 곳에 데이터를 보내준다.

ex) 쿠팡 로그인 -> 회원가입은 이미 되어있음 -> 내 장바구니로 들어옴 -> 이전에 리퀘스트에 대한 기억이 전혀없음 -> 로그인을 해도 허가를 받아야 하는 과정에서 계속 로그인을 해야하는 과정을 해결해야 하는데 방법: 토근을 발행해 주는 것임 -> 유저입력정보를 프론트엔드에서 백엔드로 받음 -> 로그인 성공 -> 제이슨 웹토큰을 받음 -> 이 토큰을 돌려받아서 다음 리퀘스트의 헤더스에 넣어줌 -> 이렇게 넣어주면 백엔드에서 다시 받아서 재 로그인을 하는 것이 아니라 아까 로그인 성공했던 토큰을 받아서 서버에 전달을 해줌 (로그인 했던 사람인지 아닌지 알 수 있음)

So, ⭐ 제이슨 웹토큰이 가장 대표적인 방법이다!!!!

📕 JOSON Web Token

  • 위의 그림은 JWT 구조이다.

📚 헤더에는 어떤 정보가 들어가는가?
1.토큰의 타입과 해시 알고리즘 정보가 들어간다.
2.해더의 내영은 BASE64 방식으로 인코딩해서 JWT 가장 첫 부분에 기록된다.
3. 해더를 먼저 보면 "여기의 토큰이 제이슨 웹토큰이다." 라는 것을 넣어주고 어떤 알고리즘을 해쉬할 것인지 헤더에 정보를 담아 준다.
예시 - {"alg":"HS256","typ":"JWT"}

📚 내용(payload)에는 어떤 정보가 들어갈까?
1. 만료시간을 나타내는 exp와 같이 미리 정의된 집합인 Registered Claim
2. 공개용 정보 전달을 목적으로 하는 Public Claim
3. 클라이언트와 서버간 협의하에 사용하는 Private Claim
4. 위의 세 가지 요소를 조합해여 작성한뒤 BASE64 인코딩을 하여, 두번째 요소르 위치한다.
예시 - {"user-id": 1,"exp":"1539517391"}

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

여기서의 암호화는 복호화가 가능하기 때문에 유저아이디가 중복이 되든말든 서버가 열쇠로 열어본다. 이 열쇠로 잠갔으니까 이 열쇠로 열어서 보았을 때 열리면 우리서버에 발급한 토큰이라는 것을 알 수 있다.

So, 당근에서 발급받은 토큰이 쿠팡에서 사용되면 x, 시크릿 키 만이 그것을 열어 볼 수 있는 것이다


생성된 JWT의 예시

2개의 댓글

comment-user-thumbnail
2022년 5월 19일

정리 왤케 잘했냐그여~! 역시 가영님👍🏻👍🏻

1개의 답글