오늘은 드디어
인증과 보안관련된 공부가 시작되었다.

image

Spring Security, JWT, OAuth2 등
여러가지를 배울 예정이고

가장 고전하는 영역이지 않을까 생각한다.


오늘은 인증, 보안에 대한 기초를 먼저 파악하고
내일부터 본격적인 Spring Security 사용법을 알아볼 것 같다.
오늘은 기초인 HTTPS와 Hashing, Cookie, Session에 대해 알아보자


HTTPS

우리가 여태까지 배웠기를 HTTP 프로토콜을 이용해
TCP/IP 통신으로 서버와 연결할 수 있다고 공부를 했었다.
HTTP Message를 통해 Json 객체를 받아보기도 하였다.

HTTPS의 Hyper Text Transfer Protocol Secure Socket layer의 약자다.
보면 알 수 있듯이 기존의 HTTP + Secure Socket layer가 붙은 모습이다.
HTTP 프로토콜을 보다 안전하게 요청을 주고 받기위해 SSL, TLS라는 알고리즘을 이용해
HTTP 통신을 하는 과정에서 데이터를 암호화하여 전송하는 방법이다.

image
HTTPS TLS HandShake (출처: CLOUDFLARE 사이트 참조 )

해당 그림은 HTTPS의 통신 핸드쉐이크이다.
클라이언트에서 접속요청이 왔을 때, 내부적으로 통신이되어지는 순서이다.

TCP 연결이 완료후 TLS 핸드쉐이크가 동작하는 모습을 볼 수 있고
TLS 핸드쉐이크 내에서는 인증서, 대칭키, 비대칭키와 같은 암복호를 통해
인증된 서버에 접속을 할 수 있게 확인을 해준다.

정말 간단하게 정리해보자면

대칭키 : 키 한개로 암복호를 한다.
비대칭키 : 암호화한 키와 복호화한키가 다르다.

키의 종류로는 공개키(Public Key)개인키(Private Key)가 존재하고

대칭키 같은경우에는 공개키-공개키, 개인키-개인키로 암호화 복호화를 할 수 있고
비대칭키 같은 경우에는 공개키-개인키, 개인키-공개키로 암호화 복호화를 할 수 있다.
HTTPS TLS 핸드쉐이크는 대칭키,비대칭키를 둘다 사용한다.

여기서 비대칭키 같은 경우에는
개인키로 암호화한것을 공개키로 복호화할 수 있는데, 목적은 인증서같은 누구나 볼 수 있는 정보고
공개키로 암호화한것을 개인키로 복호화할 수 있는데, 목적은 정보보호와 외부의 탈취방지를 위한 것이다.

여기서 인증서라는 개념이나오는데
이러한 인증서의 역할은 서버에서 인증서를 브라우저에게 보내주는데
클라이언트에 접속한 곳이 정말 해당 서버와 일치하는지 보증해주는 장치이다.
이러한 인증서를 관리해주는 공인된 기관들을
Certificate Authority 라고하며 대표적으로 AWS가 있다.

TLS 핸드쉐이크를 정리해보자면

  1. Client -> Server에게 헬로 요청
  2. Server -> Client 인증서를 포함해서 헬로 응답 (개인키로 암호화하여 전달)
  3. Client는 내장된 CA 리스트를 보고 인증서를 확인한다. (개인키->공개키 복호화)
  4. Client가 CA의 공개키로 복호화를 통해 인증서를 검증했다면 Client는 대칭키를 만든다.
  5. 이 대칭키를 서버의 공개키로 암호화해서 Client -> Server에 전달한다.
  6. 그럼 Server는 서버의 개인키로 복호화하여 클라이언트의 대칭키를 확인한다. (공개키->개인키 복호화)
  7. Server -> Client의 대칭키로 샘플 데이터를 암호화해서 클라이언트에게 보내서 확인한다.
  8. Client는 서버에게 받은 데이터를 대칭키로 복호화해서 서로 대칭키를 잘 가지고 있는지 확인한다
  9. 이 후에는 Client와 Server는 서로 대칭키로 암호화와 복호화를 진행하여 데이터를 전송한다

사실 이런 일련의 과정들은
브라우저와 서버가 해당 과정을 대신 처리해주기 때문에
개념과 순서정도만 이해하면 좋을 것 같다.


로컬 환경에서 테스트

그럼 로컬환경에서 인증서 발급과
Https 서버를 구현하는 간단한 예제를 살펴보자

우선 Tomcat WAS를 사용하기위해
스프링부트로 프로젝트를 만들었고

로컬환경에서 인증서를 만들기위해 터미널로 mkcert를 설치해야한다.

brew install mkcert

homebrew를 이용해 mkcert 설치

mkcert -install

PKCS12 형식 인증서를 생성할 수 있도록 설치

mkcert -pkcs12 localhost

내가 만든 프로젝트 resources 경로에서
위의 명령어를 실행시켜 PKCS12 인증서를 생성해주면


image

위와 같이 resources에
localhost.p12 인증서가 생긴다.

인증서가 생겼다면 application.properties 안에

server.ssl.key-store=classpath:localhost.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=changeit

와 같이 입력해주면 https로 서버를 사용가능하다.
여기서 비밀번호는 초기해 셋팅을 하지않으면 changeit으로 입력하면된다.

그리고 스프링 애플리케이션을 실행시키면

image

사진과 같이 https로 서버 구현된 것을 확인할 수 있다.


Hasing

어떤한 문자열에 임의의 연상을 적용하여
다른 문자열로 변환하는 것을 Hasing이라고 한다.

즉, 해싱한다는 의미는 어떠한 값을 암호화해준다 생각하면 될 것 같다.
여기서 해싱의 특징을 적어보자면

  1. 모든 값에 대한 해시값을 계산하는데 오래걸리지 않아야한다.
  2. 최대한 해시값을 피해야 하며, 모든 값은 고유한 해시값을 가진다.
  3. 아죽 작은 단위의 변경이라도 완전히 다른 해시값을 가져야한다.

Salt

암호화해야 하는 값에 어떤 별도의 값을 추가하여 결과를 변형하는 것이다.
영어로 소금이라는 뜻과 걸맞게 무언가 간을치는 느낌이라 생각하면 될 것 같다.

Salt의 큰 특징을 4가지 살펴보면

  1. 유저와 패스워드 별로 유일한 값을 가져야 한다.
  2. 사용자 계정을 생성할 때와 비밀번호를 변경할 때 마다 새로운 임의의 Salt를 사용해서 해싱해야 한다.
  3. 절대 재사용하지 말아야한다.
  4. DB의 유저테이블에 같이 저장 되어야한다.

쿠키는 서버가 웹 브라우저에 정보를 저장하고 불러올 수 있는 수단
이라고 생각하면 간단할 것 같다.

우리가 이전에 배운 Http 프로토콜은
무상태성(stateless)은 이전에 했던 작업에 대해 기억하지 않는 특성을 가지는데
검색을 하려는데 검색목록이 아래 표시된다든지
로그인 기억버튼을 눌러놓았는데 다음에 열어도 눌려져있다든지
우리는 요청을 보낼때 무상태성으로 동작하기때문에 이러한 내용들을 기억하지 못 하는데
브라우저에서 쿠키라는 것을 이용해 이러한 내용들을 저장해 사용할 수 있는 것이다.

한마디로 서버가 클라이언트에서 요청을 받고
클라이언트쪽에 응답할때 쿠키에 데이터를 싦어서 보내면
브라우저에서 쿠키값을 유지시키고 사용한다고 보면될 것 같다.

쿠키의 옵션으로는

domain - 서버와 요청의 도메인이 일치하는 경우 쿠키 전송
path - 서버의 요청의 세부 경로가 일치하는 경우 쿠키 전송
maxage/expires - 쿠키의 유효기간 설정
httpOnly - 스크립트의 쿠키 접근 가능 여부 설정
secure - HTTPS 에서만 쿠키 전송 여부 설정
sameSite - 같은 사이트에서만 쿠키를 사용할 수 있게 하는 설정

Session

세션은 인증해주는 방법으로
여러 페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법이다.

세션은 중요한 데이터를 서버에 저장하고 암호화된
세션id를 쿠키에 담아 클라이언트에 전달하고
세션id가 부여된 브라우저는 신분증같이 이를 이 유저는 인증에 성공했다고 알리며
다른 요청을 보낼때 마다 해당 세선id로 인증을 거치며 사용할 수 있게된다.



쿠키와 세션의 비교

  Cookie Seesion
설명 쿠키는 그저 http의 stateless
한 것을 보완해주는 도구
접속 상태를 서버가 가짐
접속 상태와 권환 부여를 위해
세션아이디를 쿠키로 전송
접속 상태
저장 경로
클라이언트 서버
장점 서버에 부담을 덜어줌 신뢰할 수 있는 유저인지 서버에서 확인
단점 쿠키 그자체는 인증이 아님 하나의 서버에서만 접속 상태를 가지므로
서버분산에 불리



오늘은 이렇게 인증, 보안에 관한
간단한 CS 지식들을 공부해보았는데
사실 처음 듣는 개념들이라 아직 어떻게 쓰이는지 감을 잡기가 어렵다.

이러한 것들이 있고 후에 학습하면서
이렇게 사용하는구나를 깨닫고 내것으로 체득을 해야할 것 같다.

오늘 공부는 여기서 끝 !


오늘의 커피량: ☕️ ☕️
오늘의 점심: 라면, 김밥