코드스테이츠 37일차 [ (인증/보안) 기초 ]

Lumi·2021년 10월 26일
0
post-thumbnail

이번 글을 통해서 우리는 로그인, 로그아웃, 회원가입 같은 기능을 구현하게 된다.

더불어 인증에 관하여 알아보자.

개인적으로 나는 이부분이 좀 신기하고 어려웠기 때문에 확실하게 잡고 갈것이다.

HTTPS

인터넷에서 데이터를 주고받는 통신 프로토콜이다.

  • 여기에서 보안이 붙은 것이다(http에서)

기존에 있는 http와 다르게 정보를 한번 암호화 하기 떄문에 키가 없다면 정보를 볼수가 없다.

  • 인증서, CA, 비대칭 키 암호화 이렇게 세가지를 활용하여 암호화 한다.

인증서

  • 데이터를 제공한 서버거 진짜 데이터를 전송한 서버인지 확인하는 데에 사용된다.
  • 인증서의 내용에 서버의 도메인 관련 내용도 담겨 있다.
  • 요청을 받게 된다면 서버는 인증서와 함께 응답을 전송하고 응답을 받은 클라이언트는 인증서에 작성된 도메인과 기존에 작성된 도메인을 확인하게 된다.
  • 같다면 서버를 인식하지만 만약 다르다면 해커에 의해 해킹이 된것이기 떄문에 서버를 믿지 않게 된다.

CA

  • 인증서를 발급하는 공인된 기관
  • 자격이 항상 유지되는 것이 아니라 시간이 지남에 따라서 자격이 박탈 당할 수도 있다.

비대칭 키 암호화

  • 전혀다른키 한쌍으로 암호화 및 복호화를 진행한다.
  • A키로 암호화를 한다면 복호화 하는데에는 한 쌍인 B키로 복호화를 가능
  • 그러기 떄문에 키 하나는 숨겨두고 하나는 공개를 하게 된다.
  • 키 생성은 매우 복잡한 알고리즘이기 떄문에 모든곳에서 사용을 하게 되면 속도가 많이 저하된다.
  • 그러기 떄문에 간의 통신의 초창기 에서만 사용하게 된다.

통신이 이루어 지는 순서

Hand Shake

  • 서로를 확인하고 서버에서 공개키 하나를 클라이언트에 제공을 한다.

비밀 키 생성

  • 그러면 전달받은 키를 이용하여 서버와 키를 만들어낼 정보를 암호화하여 전송을 한다.
  • 서버 또한 통신할 정보를 암호화 하여 전송을 한다.
  • 이렇게 서로 통신한 정보를 바탕으로 비밀키를 생성한다.

상호 키 검증

  • 이후 서로 만들어진 키로 암호화 복호화를 반복하며 데이터를 주고받게 된다.

이후에 이러한 키를 바탕으로 데이터를 전송할떄 암호화, 복호화시킨다.

Learn About HTTPS

앞서 말했듯이 http를 보안화한 프로토콜이다.

  • http요청을 ssl 혹은 tls라는 알고리즘을 이용해 통신하는 과정에서 내용을 암호화한다.

클라이언트는 데이터 제공자가 제공해준 데이터를 사용할수 밖에 없다.

  • 서버에 요청을 하고 데이터를 받아서 처리를 하기 떄문에

그러기 떄문에 서버에서 받아오는 과정에서 가로채는 중간자 공격에 매우 취약하게 된다.

  • 정보를 해킹한뒤에 변조시켜 다시 클라이언트에 전송하는 공격

그러기 떄문에 암호화라는 과정이 필요하다.

HTTPS 프로토콜의 특징

    1. 암호화된 데이터를 주고받기 떄문에 중간에 탈취가 일어나도 그 내용을 알아볼 수 없다.
    1. 서로 인증서를 비교해 가면서 CA의 정보를 확인한다.

ssl

  • 디지털 인증서 라고도 한다.
  • 브라우저 또는 사용자의 컴퓨터와 서버 또는 웹사이트 간에 암호화된 연결을 수립하는데 사용

tls

  • ssl프로토콜에서 발전한 프로토콜
  • 마찬가지로 개인정보를 보호하는데에 목표를 둔다.
  • ssl과 상호 운영되지는 않으며 기밀성과 데이터 무결성을 보장한다.

Hashing

부가적인 인증 과정이 없이 요청을 하여 데이터를 받아오는 과정은 매우 간단하다.

  • 그냥 서버에 요청에서 서버에서는 DB에서 값을 가져와 클라이언트에게 보내주면 된다.

하지만 보안을 생각해서 패스워드를 입력해야만 값을 가져온다고 해보자

  • 서버에 패스워드를 입력하여 값을 요청하고 서버에서는 DB에서 패스워드를 비교하여 값을 가져온뒤 그 패스워드를 비교

이 방법은 보안의 역할을 할 수가 있다.

하지만 만약 우리가 패스워드가 유출된다면 해킹의 위협에 전면적으로 노출되게 된다.

  • 당연한 소리이다. 개인 계정의 패스워드를 노출하면 누구든지 해당 아이디로 로그인 할수 있는 것과 같다.

그러기 떄문에 우리는 암호화를 사용해야 한다.

  • 내 비밀번호는 1234인데 이것을 암호화하여 저장을 하는 것이다.

암호화

  • 일련의 정보를 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람만 이해할수 있게 정보를 관리하는 과정

앞서 적은 예시를 암호화 하는 과정을 살펴보자

1234라는 비밀번호를 입력하여 서버에 데이터를 요청하고 서버에서는 1234라는 비밀번호를 확인한뒤 DB에 있는 비밀번호와 대조를 해본다.

  • 하지만 이 방법은 말했듯이 해킹을 당하기가 쉽다.

그럼 서버측에서 값을 DB에 저장을 할떄 +2만큼 더한값을 저장한다고 생각을 해보자.

  • 1234 -> 3456

그럼 클라이언트가 1234라는 패스워드를 요청을 하면 서버에서는 3456으로 값을 DB에 저장을하고
3456에 맞는 값을 전해준다.

이떄 만약 해킹이 되어서 3456이라는 값이 노출된다고 해도 괜찮다.

  • 왜냐하면 기존의 비밀번호는 1234이기 떄문에
  • 어떻게 기존의 값을 암호화하였는지 모른다면 DB에 있는 비밀번호가 노출되어도 괜찮다.

이런 원리로 암호화를 적용시킬수가 있다.

  • 보통은 해쉬 암호화를 사용한다.

Hashing암호화 조건

1. 모든 값에 대해 해시값을 계산하는데에 오래걸리지 않아야 한다.

  • 오래 걸리게 된다면 브라우저의 속도가 저하된다.

2. 최대한 해시 값을 피애햐 하며 모든 값을 고유한 해시값을 가진다

  • 개인적으로 이부분은 고려하지 않아도 된다고 생각한다.
  • 왜냐면 해시값의 경우의 수는 너무 크기 떄문에

3. 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.

  • 2번과 동일하다.

요즘에는 SHA256이라는 해시 알고리즘을 많이 사용한다.

Salt

암호화 해야하는 값에 어떤 별도의 값을 추가하여 결과를 변형 시키는것

앞서 말한것처럼 암호화를 하면 안전해 보이지만 해커가 만약 해쉬된 값을 디코딩하여서 패스워드를 알아올수도 있다.

  • 레인보우 테이블

그러기 떄문에 기존의 패스워드 값에 약속된 별도의 문자열(Salt)를 추가하여 해쉬를 진행한다면

좀더 안전한 암호화를 이루어 낼수가 있다.

기존 : 패스워드 => 해시값
변형 : 패스워드 + Salt => 해시값

Salt 사용 시 주의사항

1. 유저와 패스워드 별로 유일한 값을 가져야 한다.
2. 계정 생성, 계정 변경 할떄마다 새로운 임의의 Salt를 사용해야한다.
3. Salt는 절대 재사용 되어서는 안된다.
4. Salt는 DB의 유저 테이블에 같이 저장되어야 한다.

Cookie

인증에 필요한 기본 지식이다.

HTTP요청은 stateless하다.

  • 이전 요청과 무관한 각각으로 요청을 독립적인 트랜잭션으로 취급한다.

그럼 우리가 장바구니를 생각해보자

쇼핑을 하면서 장바구니에 마음에 드는 물건을 담고 계속 인터넷 쇼핑을 한다.

하지만 http요청은 statelss한데 어떻게 이전에 있는 상태를 계속 유지 할까??

  • 우리가 배운 대로라면 트랜잭션이 종료되었기 떄문에 장바구니에 있는 값은 없어져야 할것이다.

하지만 장바구니가 유지되고 이렇게 유지되는 이유는 모두 Cookie떄문이다.

Cookie : 어떤 사이트를 들어갔을떄 서버가 일반적으로 클라이언트에 전달하는 작은 데이터

  • 의사를 물어볼떄도 있고 물어보지 않을떄도 있다.

서버가 웹에 정보를 저장하고 불러올 수 있는 수단이며 해당 도메인에 쿠키가 존재하면 클라이언트 상에서 요청을 할때마다 자동으로 쿠키를 포함해서 전송한다.

  • 즉 장바구니에 아이템이 있다는 쿠키(정보)를 요청을 할떄마다 함께 전송을 하여 계속 갱신 시키는 것이다.
  • 로그인 상태 유지 같은 곳에서도 쿠키를 사용한다.
  • 쿠기를 별도로 삭제하지 않으면 계속 웹에서 존재하기 떄문에

하지만 브라우저에 존재하기 떄문에 보안상으로 매우 위험하다.

  • 그래서 암호화 하여 쿠키를 보관한다.

1. Domain

  • 서버와 요청의 도메인이 일치하는 경우에만 쿠키를 서버에 전송

2. Path

  • 서버와 요청의 세부경로가 일차하는 경우 쿠키 전송

3. MaxAge or Expires

  • 쿠키의 유효기간 설정

4. HttpOnly

  • 스크립트의 쿠키 접근 가능 여부 결정

5. Secure

  • HTTPS프로토콜에서만 쿠키 전송 여부 결정

6. SameSite

  • CORS요청의 경우 옵션 및 메서드에 따라 쿠키 전송 여부 결정

예시

pc방에서 로그인을 한뒤 로그아웃을 하지 않고 나왔다고 생각을 해보자

쿠키는 웹에 저장이 되기 떄문에 로그아웃을 하지 않으면 쿠키가 계속 웹에 저장이 되어 있을 것이고 그러면 타 사용자가 웹에 있는 쿠키를 활용하여 나의 정보를 취득할수 있다.

이떄 사용하는 Option은 MaxAge or Expires를 사용하여 일정 시간후 쿠키를 삭제시킨다.

쿠키는 js로 접근을 할수가 있다.

그러기 떄문에 js파일을 삽입해서 실행한 결과값을 확인할수 있는 XSS공격에 매우 취약하다.

이떄 사용하는 Option은 HttpOnly를 사용하여 보안을 강화한다.

만약 csrf공격의 상황이 있다고 생각을 해보자.

  • csrf:위조된 요청을 사용자에게 보내 해당 링크를 타게 되면 인증정보, 개인정보를 취득하는 공격

내가 은행에 로그인하고 은행사이트에서 나에게 인증정보를 주게 되었을떄 공격자가 나에게 악의적인 링크를 보내 내가 해당 링크로 들어가게 되었다고 하자.

  • 그러면 공격자는 나의 쿠키, 인증정보 등을 취득하게 된다.

그렇게 공격자는 나의 인증정보를 가지고 은행에서 돈을 인출하게 된다.

이떄 사용하는 Option은 SameSite이다. 이전에 내가 로그인했던 사이트 정보와 일치하지 않으면 쿠키를 허용하지 않는 옵션

쿠키는 쉽게 말하면 서버에서 클라이언트에 저장하는 데이터이다.

  • 클라이언트가 요청을 보낼떄 대개 쿠키를 담아서 요청을 보내게 된다.

항상 쿠키를 담아서 보내는 것은 아니고 설정한 Option에 맞춰서 쿠기를 전송한다.

  • Option은 상황에 맞게 설정을 한다.

Domain

요청해야 할 url이 http://www.localhost.com:3000/users/login 이라면
여기에서 Domain은 localhost.com이 되고
해당 Domain이 있는 요청만 쿠키를 담아서 전송한다.

Path

세부 경로는 서버가 라우팅할 떄 사용하는 경로이다.
요청해야 할 url이 http://www.localhost.com:3000/users/login 이라면
여기에서 Path는 /users/login이 되고
해당 Path가 있는 요청만 쿠키를 담아서 전송한다.

MaxAge or Expires

쿠키의 유효기간을 설정한다.
MaxAge는 앞으로 몇 초 동안 쿠키가 유효한지 설정을 하고
Expires는 언제까지 유효한지 날짜를 지정한다.
하지만 두 옵션이 모두 지정되지 안흔ㄴ다면 브라우저의 탭을 닫으면 쿠키가 제거될수 있다.

Secure

쿠키를 전송해야 할떄 사용하는 프로토콜에 따른 쿠키 전송 여부를 결정한다.
만약 true라면 HTTPS프로토콜을 이용하여 통신하는 경우에는 쿠키를 전송한다.

HttpOnly

js에서 쿠키에 접근 여부를 결정한다.
true라면 JS에서 쿠키게 접근이 불가능하다.
기본적으로 false로 지정되어 있으며 false인 경우에 JS를 통해 쿠키에 접근할수 있기 떄문에 'XSS공격'에 취약하다.

SameSite

Cross-Origin요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정한다.
Lax : Cross-Origin요청이면 GET메소드에 대해서만 쿠키를 전송
Strict : same-site인 경우에만 쿠키를 전송(Cross-Origin = x)
None : 모든 경우에 대해서 쿠키를 전송

  • 이떄에는 Secure옵션이 필요하다.

이러한 옵션들을 지정한 뒤에 서버에서 클라이언트로 쿠키를 처음 전송하게 될떄 헤더에 Set-Cookie라는 프로퍼티에 쿠키를 담아 쿠키를 저놋ㅇ한다.

이후 클라이언트 에서 쿠키를 전송해야 한다면 클라이언트는 헤더에Cookie라는 프로퍼티에 쿠키를 담아 서버에 전송한다.

쿠키를 이용한 상태 유지

쿠키는 웹에서 사용하는 작은 DB라고 생각해도 좋다.

유도리있게 사용하면 Stateless한 인터넷에서 Stateful하게 이용을 할수 있지만

앞서 말했듯이 설정을 잘못하면 오랜시간 유지 가능하고 공격에 취약하기 떄문에 정확히 알고 사용을 해야한다.

CSRF

여러가지 해킹의 공격기법중 하나이다.

주소가 다른 사이트에서 요청을 조작 하는것

  • 간단한 예시로는 스팸 문자 등이있다.
  • 이상한 문자로 링크가 전송되고 그 링크를 클릭하면 내 개인정보가 빠져나가는 것과 같다.

요청만을 조작하는 해킹이기 떄문에 해커가 직접 응답에 접근할수는 없다.

CSRF공격을 하기 위한 조건

  1. 쿠키를 사용한 로그인
  • 유저가 로그인 했을 떄 쿠키로 어떤 유저인지를 알 수 있어야 한다.
  1. 예측할 수 있는 요청/parameter를 가지고 있어야 한다.
  • request에 해커가 모를 수 있는 정보가 담겨있으면 안됨

a가 사이트에 로그인을 한뒤 get요청을 이용하여 은행에 100만원을 보냈다.
그러면 해커는 get요청 쿼리에 있는 계좌번호를 자신의 계좌번호르 바꾼다.
그러기 위해서 a가 특정 링크를 클릭하게 만들고 요청을 바꾸는 것이다.

CSRF공격을 막기 위한 방법

  1. CSRF토큰을 사용
  • 서버측에서 공격을 막기 위해 토큰 문자열을 사용자 에게만 제공
  1. Same-site cookie사용
  • 같은 도메인에서만 세션/쿠키를 사용

Session

  • 클라이언트와 서버간에 활성화된 상태
  • 사용자가 인증에 성곤한 상태

쿠키 같은 경우에는 클라이언트에 저장을 한다.

하지만 Session은 서버에 저장을 하게 되고 쿠키 안에 세션id가 암호화된 데이터만을 제공한다.

즉 쿠키 안에 있는 Session의 id값을 이용해 서버에 있는 Session의 데이터를 가져올수 있다.

a라는 유저가 물품을 장바구니에 담으려고 한다.
그러면 서버에 요청을 하게 될것이고 서버는 해당 물품을 DB에 저장을 하게 된다.
- 처음에는 인증정보가 없기 떄문에 password를 통해서 인증을 한다.

그후 DB에서 Session_id를 반환하여 주고 그것을 쿠키안에 담아서 반환을해주게 된다.
- 쿠키는 경우에 따라서 JS로 변환이 가능하기 떄문에 Session은 반드시 암호화를 해주어야 한다.

이후 다시 a라는 유저가 또다른 물품을 장바구니에 담고자 한다면 이번에는 기존에 있는 Session_id를 이용한다.
- 처음에 쿠키를 받을떄에 Session_id를 받았기 떄문에 이 값을 가지고 같은 사용자임을 증명한다.

이렇게 데이터 인증이 이루어 지게 된다.

  • 쿠키와 세션의 차이점을 간략하게 정리한 사진이다.

어떻게 보면 쿠키와 세션은 비슷하다.

  • 하지만 내식대로 이해를 하면 쿠키는 그저 장바구니이고 쿠키안에 인증할수 있는 정보를 담고 활용한다고 생각한다.

사실 쿠키만으로도 인증을 할수는 있다.

  • 앞서 설명했던것을 참고하자.

하지만 Session을 사용함으로써 추가적으로 얻을수 있는 이점이 있다.

  • Session의 이점이라기 보다는 두가지 인증을 사용할떄 얻을수 있는 이점이다.
만약 동일한 Session_id를 가지고 있는 a,b가 있다고 해보자

a는 미국, b는 한국에 살고 있으면 서로 다른 사용자일 것이다.

하지만 Session_id가 동일하기 떄문에 두 사용자는 Session만을 이용한 증명에서는 반드시 통과하게 될것이다.

하지만 쿠키값이 다르기 떄문에 같은 사용자라고 인식을 하지 않을수 있다.

** 이처럼 두가지를 통해서 인증하는 방법은 좀더 안정적인 통신을 보장한다. **

Session의 단점

우리는 사용자의 입장에서 생각해야 하기 떄문에 일단 속도가 빨라야 한다.

  • 블록체인은 속도가 느린편이지만;; 어쩃든 ㅎ

앞서 설명했듯이 Session은 서버에서 저장을 하게 된다.

만약 사용자가 많아지게 된다면 Session은 서버 메모리 영역에서 한 일부분을 차지하게 될것이다.

  • 그러면 속도가 느려지는건 당연한 결과이다.

또한 Session은 한 서버에 하나의 Session만을 다룰수 있다.

  • 이 단점을 보완한것이 Token이다.

또한 XSS위험에 노출될수가 있다.

  • 왜냐면 어차피 쿠키에 담기 떄문에 쿠키가 해킹당하면 Session_id또한 해킹당하게 된다.
profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글