어떠한 것을 적용하고 사용해볼 때는 이것이 무엇이고 왜 사용되며, 언제 쓰는 건지가 가장 중요하다.
또한, 새로운 기술을 배울 때 그 기술이 원초적으로 이해가 가지 않는다면 배경지식이 많이 부족하다는 것을 뜻한다. 따라서 기술을 바로 사용할 수 있더라도 이해가 되지 않았기 때문에 진정으로 나의 것이라고 할 수 없다.
JWT가 무엇이고, 왜 사용되는지 그리고 언제 사용하는 것인지에 대해 알아볼 것 이다.
세션
- 보통 로그인 요청(인증) 시 사용함
- 세션 사용 과정
- 최초 요청 시, HTTP 헤더(Set-Cookie)에 Session ID를 포함해서 클라이언트에게 응답함
- 웹브라우저는 부여된 Session ID를 쿠키에 저장해두고, 다음 요청 때마다 해당 쿠키를 HTTP 헤더에 넣어서 전송함
- 세션이 삭제되는 경우
- 서버가 세션의 값을 날렸을 때
- 사용자가 브라우저를 종료했을 때
- 만료 시간이 되면(보통 30분) 자동 삭제
- 문제점
- 세션은 사용자의 수 만큼 서버 메모리를 차지함
- 서버를 다중화했을 경우, 세션 불일치 이슈 발생
- 해결 방안: 스티키 세션, 세션 클러스터링, 세션 스토리지
- 최근에는 이를 보완하는 토근 기반의 인증방식을 많이 사용함(stateless)
- ex) JWT(JSON Web Token)
TCP
OSI 7계층
1. 응용계층 : 응용 프로그램
2. 프레젠테이션 계층 : 암호화, 압축
3. 세션 계층 : 인증 체크
4. 트랜스포트 계층 : TCP or UDP 통신
5. 네트워크 계층 : IP
————————————여기까지 WAN통신——————————————
6. 데이터링크 계층 : 데이터를 전송 및 물리 주소 결정
7. 물리 계층 : 물리적 연결
————————————여기까지 LAN 통신 ——————————————
- 한 번 통신이 일어날 때마다 이 과정을 직렬화(1계층 ➙ 7계층)와 역직렬화(7계층 ➙ 1계층)를 거침
TCP vs UDP
- TCP ➙ 신뢰성있는 통신
- 데이터를 전송하면 응답 받은 쪽에서 잘 받았다는 의미로 ACK 신호를 보냄
- 보통 우리가 공부하는 웹은 TCP 통신을 함
CIA
CIA(Confidentiality Integrity Availability)
- 기밀성(Confidentiality)
- 송신하고자 하는 정보의 내용을 다른 사람이 보지 못하게 하는 것
- 무결성(Integrity)
- 정보의 변경이 있는지 없는지를 확인하는 기능
- 내용의 변경이나, 훼손없이 정확하게 보존
- 가용성(Availability)
- 인가된 대상자에게만 제공
- 암호화를 할 경우, 가용성은 떨어져도 기밀성은 유지할 수 있음
A나라가 B나라에게 문서를 전달하는데, 중간에 C나라가 그 문서를 탈취한다. ➙ 기밀성 깨짐
A나라가 B나라에게 문서를 전달하는데, 중간에 C나라가 문서를 위조해 전달한다. ➙ 무결성 깨짐
B나라는 A나라가 보내준 문서(사실은 C나라가 위조시킨 문서)를 전달 받는다. ➙ 가용성 깨짐
# 가용성을 지키는 방법
C나라 보다 강한 전사들을 보냈지만, C나라에 더 강한 전사들이 있으면 문서를 탈취당한다.
# 기밀성을 지키는 방법
문서를 암호화해서 보내더라도 중간에 C가 문서를 탈취하면 소용이 없다.
따라서 훔쳐봐도 열어볼 수 없게 잠궈서 열쇠로만 열 수 있게하면 무결성을 지킬 수 있다.
- 문서를 K라는 열쇠로 잠그고(암호화) 보낸다.
- C나라는 문서를 못열지만 B도 마찬가지로 열쇠가 없어 못여는 문제가 발생한다.
- 따라서 열쇠를 전달해야 하는데, 이 열쇠도 도난 당하면 CIA가 깨지게 된다.
- 보안 문제 발생
- 열쇠(보안키-개인키) 전달의 문제
- Data(문서)가 누구로부터 왔는지 검증에 대한 문제(인증 문제)
RSA(암호화)
- 공개키 기반 암호화
- Public Key(공개키), Private Key(개인키) 사용
- 공개키로 암호화 시, 개인키로만 복호화 가능 (
암호화에 자주 사용) - 개인키로 암호화 시, 공개키로만 복호화 가능 (
전자 서명에 자주 사용)
- 열쇠 전달 문제 해결
- A나라는 메시지(열쇠)를 B의 공개키로 암호화하여 전달하면, C가 중간에 가로채도 내용을 볼 수 없다.
- Why? B의 개인키로만 메시지(열쇠)를 열 수 있기 때문
- 인증 문제 해결
- A나라는 메시지를 A의 개인키로 암호화하여 전달하면, B나라는 A의 공개키로 복호화하여 열게 된다.
- A의 개인키를 가지고 있는 것은 A밖에 없다. 따라서 A의 공개키로 열었다는 것은 A가 보냈다는 의미이다.
- 이처럼 개인키로 잠궜다는 것은 전자서명을 의미하기 때문에 인증 문제를 해결할 수 있다.
- 메시지를 B의 공개키로 암호화하고, 이를 다시 A의 개인키로 암호화하면 두 문제를 모두 해결할 수 있다(CIA도 모두 해결).
- B는 문서를 A의 공개키로 복호화하고, 열리면(인증 O) 다시 B의 개인키로 복호화한다.
RFC 문서
- HTTP : 벨 연구소에서 월드 와이드 웹(www)이 등장함
- 내부망 연결 방식이 다른 두 지점(A,B)에서 통신을 하려면 약속된 규칙이 필요하다.
- 이 약속된 규칙이 RFC 1번 문서이다. (최초 문서)
- 즉, RFC 문서는 서로 다른 내부망끼리 통신하기 위해 약속된 규칙이 정의된 문서로, 이 문서를
프로토콜이라고 한다.
- 또 다른 곳과 통신을 하기 위해 RFC2번 문서가 만들어지고, 약속을 하나하나 하면서 네트워크 망이 점점 커지고 많아지게 된다.
- 이 네트워크들이 모여서 만들어진 것이 www(월드 와이드 웹) 인터넷이다.
- 즉, 인터넷은 RFC 문서들로 이루어져 있고, 서로 한 약속을
HTTP 프로토콜이라고 한다.- 또 다른 내부망을 가진 집단이 www로 들어오려 할 때도 www와 약속(프로토콜)이 필요한데, 이때 www에서 동의하지 않으면 RFC문서로 만들어지지 않는다.
- 그래서
JWT(RFC 7519)는 www에서 인정한 7519번째에 만들어진 RFC 문서(약속)라는 것이다.
JWT(JSON Web Token) 구조
JWT란?
- 웹표준(RFC 7519)로서 JSON 객체를 사용하여 안전하게 정보를 전송하기 위한 방식
- JWT는 서명 알고리즘(HMAC SHA256 또는 RSA)을 사용함
- JWT로 주고받는 정보는 디지털 서명되어있기 때문에 신뢰할 수 있음
- JWT는 정보를 암호화하여 주고받을 수는 있지만, 서명된 토큰에 중점을 둔 것
- 로그인 및 정보 교류의 상황에 사용함
- 유저가 로그인하면 서버는 유저의 정보에 기반한 토큰을 발급하여 유저에게 전달한다. 그 후 서버에 요청할 때마다 JWT 토큰을 포함하여 전달하고, 서버는 해당 토큰의 유효성 및 인증을 검증하고 작업을 처리한다. 서버는 유저의 세션을 유지할 필요가 없고, 로그인되어있는지 신경쓸 필요가 없다.
- JWT는 두 개체 사이에 안정성 있는 정보를 교환하기에 좋은 방법이다. 정보가 서명되어있기 때문에 보낸이가 바뀌지 않았는지, 정보가 조작되지 않았는지 검증할 수 있다.
JWT 구조
- JWT는
Header,Payload(내용),Signature(서명)의 세 부분으로 이루어져있음- JSON 형태인 각 부분은 Base64로 인코딩되어 표현됨
- Base64는 암호화된 문자열이 아닌, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환함
- 각 부분을 이어주기 위해
.구분자를 이용하여 구분함
- JSON 형태인 각 부분은 Base64로 인코딩되어 표현됨
Header(헤더)
{
"alg" : "HS256",
"typ" : "JWT"
}
- 암호화할 알고리즘과 토큰의 타입을 지정함
Payload(내용)
{
"iss": "xxx.com", # 토큰 발급자
"exp": "10000000", # 토큰 만료시간
"https://xxx.com/jwt_claims/is_admin": true, # 공개 클레임
"userId": "xxx", # 비공개 클레임
"username": "zz" #비공개 클레임
}
- 토큰에 담을 정보가 들어있는데, 담는 정보의 한 조각을 클레임(Claim)이라고 부름
- 클레임은 Json(key-value) 형태의 한 쌍으로 이루어져있고, 토큰은 여러 개의 클레임을 넣을 수 있음
- 클레임 종류
- 등록된(Registered) 클레임
- 서비스에서 필요한 정보가 아닌 토큰에 대한 정보를 담기 위해 이름이 정해진 클레임
- 발급자, 제목, 대상자, 만료시간 등
- 공개(Public) 클레임
- 해당 클레임인 충돌이 방지된 이름을 가지고 있어야하기 때문에 클레임 이름을 URI 형식으로 짓음
- 비공개(Private) 클레임
- 양 측(클라이언트와 서버)간의 협의 하에 사용되는 클레임 이름
- 이 비공개 클레임에 사용자 정보를 넣음
- 등록된(Registered) 클레임
Signature(서명)
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
- 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드
- 헤더와 페이로드의 값을 각각 Base64로 인코딩
- 인코딩한 값을 비밀키를 이용해 헤더에서 정의한 알고리즘으로 해싱
- 해싱한 값을 다시 Base64로 인코딩하여 생성
- 생성된 토큰은 HTTP 통신을 할 때
Authorization이라는 key의 value로 사용됨- 일반적으로 value에는 Bearer가 붙여짐
{
"Authorization" : "Bearer {생성된 토큰 값}"
}
Basic, Bearer 방식
Token 인증 방식
- 세션의 문제점 해결
- 서버에 저장하기 때문에 서버 메모리 차지
- 서버가 여러 대 일 경우 세션 불일치
- 세션의 단점 - 동일 도메인에서만 사용 가능
- 쿠키의 기본 정책은 동일 도메인에서만 요청이 올 때 발동한다.
- 동일 도메인에서의 요청이 아니면 쿠키는 날아감(서버에서 쿠키를 거부)
- 그래서 javascript에서 요청할 때 Ajax로 헤더에 쿠키를 강제로 담아서 보낼 수가 있는데, 서버에서는
HTTP Only설정을 해 거부당함HTTP Only = true: 외부에서 HTTP 요청이 아닌 javascript 요청이 들어오면 거부되는 설정HTTP Only = false로 풀어주면, 외부에서 javascript로 장난을 많이 치기 때문에 true로 설정하는 편
- 쿠키의 기본 정책은 동일 도메인에서만 요청이 올 때 발동한다.
- 쿠키를 사용하지 않아도 되기 때문에, 쿠키를 탈취당했을 때의 보안 취약점도 사라짐
- 서버가 여러 대여도 Secret Key 키만 알고있으면 되기 때문에 보안 취약점도 사라짐
Authorization
- 서버로 요청을 보낼 때, 요청 헤더에
Authorization : <type> <credentials>을 담아서 보냄- type은 여러 가지가 있는데 그 중에서
Basic과Bearer가 있음
- type은 여러 가지가 있는데 그 중에서
Basic- 사용자 ID와 PW(인증 정보)를 Base64로 인코딩한 값을 토큰으로 사용함 (RFC 7617)
- Basic 토큰 값이 노출이 되면 ID, PW가 노출되는 것이기 때문에 보안에 취약함
Bearer(JWT 인증 방식 타입)- 일반적으로 JWT(RFC 7519) 같은 OAuth 토큰을 사용함(RFC 6750)
- Basic 방식과는 달리 토큰에 ID, PW 값을 넣지 않음(보안성)
- 로그인 시 토큰을 부여받고, 이후 요청할 때 요청 헤더에 토큰을 실어서 보내기 때문에 세션 저장소가 필요가 없고, 토큰 자체에 내장이 되어있음
- 유효시간이 지나면 새로운 토큰을 서버에서 주기 때문에 훨씬 안전하게 인증할 수 있음
- STATELESS, 무결성, 보안성이 장점
'Web > Web' 카테고리의 다른 글
[WEB] Web Server / Web Container / Web Application Server (0) | 2022.08.31 |
---|---|
[WEB] 자바 백엔드 웹 기술 역사 (0) | 2022.03.30 |
[WEB] HTML, HTTP API, CSR, SSR (0) | 2022.03.30 |
[WEB] 동시 요청 - 멀티 쓰레드 (0) | 2022.03.29 |
[WEB] 서블릿 (0) | 2022.03.29 |