-
0. JWT란?
-
1. Session에 대해서
-
1-1. 클라이언트가 서버에 최초 접근한 경우
-
1-2. Request Header에 Session ID를 들고 접근한 경우
-
1-3. Session이 사라지는 경우
-
1-4. 보통 Session이 사용되는 로그인 요청 & 인증
-
1-5. Session의 단점
-
1-6. 해결책
-
2. TCP에 대해서
-
2-1. OSI 7계층
-
2-2. TCP/UDP
-
3. CIA에 대해서 (보안)
-
3-1. CIA
-
3-2. CIA를 지키는 방법
-
4. RSA에 대해서
-
4-1. RSA
-
4-2. Key 전달 문제 해결
-
4-3. 누구로부터 왔는지에 대한 문제 해결
-
5. CORS에 대하여
-
5-1. JWT의 토큰 인증 방식
-
5-2. 여러 도메인에서의 Session/Cookie !?
-
5-3. CORS(Cross-Origin Resource Sharing)
-
6. Basic / Bearer Authentication
-
6-1. Basic Authentication
-
6-2. Bearer Token
0. JWT란?
JWT(JSON Web Token)는 정보를 안전하게 전송하기 위한 간단한 토큰 기반의 오픈 표준이다.
Header(헤더), Payload(페이로드), Signature(서명) 세 부분으로 구성되어 있으며........... 는 잠시 제쳐두고!!
JWT가 어떻게 쓰고, 어떻게 생겼는지. 보다는
"왜 사용되고, 어디에 사용하는지"가 더욱 중요하다!!!
항상 공부를 할 때, 블로그에서 긁어와서 코드를 돌아가게 만드는 것은 의미가 없다고 생각하는 편이다.
근본적으로 왜 사용되고, 어디에 사용되고, 그 이후에 어떻게 사용하는지를 배우는 서순이 맞다고 생각한다.
1. Session에 대해서
세션(Session)은 웹 애플리케이션에서 클라이언트와 서버 간의 지속적인 상태를 유지하기 위한 메커니즘이다.
HTTP 프로토콜은 기본적으로 상태를 유지하지 않는(stateless) 프로토콜이다!
즉, "상태를 기억할 수 없는 금붕어 같은 친구"라는 것이다...
클라이언트의 각 요청은 서버에 의해 완전히 독립적으로 처리된다.
하지만 세션을 사용하면 클라이언트의 여러 요청 간에 상태를 공유할 수 있다.
만약에 해당 client가 server에 방문한 적이 있는지!? 에 관한 이야기라면,
아주 간단한 방법으로, Session에 "방문한 적 있음 카드"를 작성해서 client에게 Response와 함께 주면 된다.
그리고 "너 다음에 방문할 때는 이거 들고와!"라는 방식을 쓰는 것이다.
1-1. 클라이언트가 서버에 최초 접근한 경우

1-2. Request Header에 Session ID를 들고 접근한 경우

1-3. Session이 사라지는 경우
1) 서버 측에서 Session을 강제로 지우는 경우
2) 사용자가 브라우저를 종료할 때
3) Session 만료 시간이 지났을 때 (보통 30분)
1-4. 보통 Session이 사용되는 로그인 요청 & 인증
Session ID : 1234는 (이미 접근한 계정)
Session ID : 3456은 최초 접근 계정이라고 가정하자.
- 1 ~ 4 : 최초 접근
- 5 ~ 10 : 로그인

- 이후 "user 정보가 필요한 페이지" 요청

* 정리
민감한 정보를 요청할 경우,
요청 헤더에 있는 Session ID를 확인해서 / 해당 User인지를 판별하고
필요한 정보를 제공해준다.
1-5. Session의 단점
Client가 몇 백 만명 이라면....?
동시 접속자 수가 서버가 처리할 수 있는 인원이 넘어버리면..?
-> 나머지는 모두 대기ㅠㅠ
=> 자주 사용하는 해결책이 "서버를 여러개 두는 것 ; Load Balancing"
그런데 문제는 여기서 발생한다.
서버를 여러개 두면, Session 저장소도 각각 따로 두게 된다는 점
1번 서버에 첫 요청을 보내놓고, 2번 서버에서 재요청을 하게 되면,
2번 서버는 해당 Client를 처음 온 친구로 인식하게 된다는 점.

1-6. 해결책
- Sticky Session을 이용해 그 사용자가 갔던 서버로만 보내는 것이다.
- 모든 서버에 세션이 생성 될 때마다 세션을 복제 시킨다. (동기화)
- DB에 세션 정보를 저장한다. (DB에는 IO가 일어나기 때문에 속도가 엄청나게 저하..)
-> 세션 사용의 장점을 파괴ㅋㅋ
메모리 공유 서버 (RAM)를 이용한다! (주로 Redis를 사용) - JWT를 사용하면 이 문제들을 해결 할 수 있다.
2. TCP에 대해서
컴퓨터 네트워크의 내용이다... 컴공생들은 아는 내용 ㅠ 간단하게 하고 넘어가겠다!
2-1. OSI 7계층

- 4번 째인 Transport 계층에서 TCP/UDP 통신 여부를 결정한다.
2-2. TCP/UDP
1) TCP (Transmission Control Protocol):
신뢰성: TCP는 연결 기반의 프로토콜로, 데이터 전송 시 신뢰성을 중요시 한다!
데이터가 전송되면 수신 측에서 확인 응답(ACK)을 보내고, 만약 손실이나 오류가 발생하면 재전송을 수행!
순서 보장: TCP는 데이터의 전송 순서를 보장한다.
흐름 제어와 혼잡 제어
연결 지향
속도 매우 느림
2) UDP (User Datagram Protocol):
신뢰성: UDP는 비연결성 프로토콜로, 신뢰성이 TCP보다 낮다. 오류가 발생하면 복구나 재전송이 이루어지지 않는다.
순서 보장 없음: UDP는 데이터의 순서를 보장하지 않는다.
흐름 제어와 혼잡 제어 없음
연결 지향이 아님
빠른 전송 속도 : 실시간에 자주 쓰임
-> 우리 웹은 TCP/IP 통신을 한다!
3. CIA에 대해서 (보안)
3-1. CIA
CIA는 정보 보안의 기본 원칙을 나타내는 약어이다.
각각 Confidentiality(기밀성), Integrity(무결성), Availability(가용성)을 나타낸다.
데이터/ 네트워크 보안 등에서 매우 자주 들어본 단어들일 것이다.
1) Confidentiality (기밀성):
정의: 기밀성은 정보에 대한 무단 접근을 방지, 오직 허가된 사용자나 시스템만이 해당 정보에 접근할 수 있도록 하는 원칙
목표: 민감한 정보가 무단으로 노출되는 것을 방지하여 정보의 비밀성을 유지한다.
2) Integrity (무결성):
정의: 무결성은 정보가 정확하고 변조되지 않았음을 보장하는 원칙이다.
목표: 정보가 변경되거나 조작되지 않도록 하여 데이터의 신뢰성을 보장한다.
3) Availability (가용성):
정의: 가용성은 정보나 시스템이 필요할 때 항상 사용 가능한 상태를 유지하는 원칙이다.
즉, 서비스의 지속적인 이용이 보장되어야 한다.
목표: 서비스 중단을 최소화하고 사용자가 필요할 때 항상 정보나 서비스에 접근 가능하도록 해야 한다.
---
쉽게 말해서, A -> B 로 데이터를 전송한다고 해보자.
1. 해커가 데이터를 중간에 빼돌렸다. -> 기밀성 위반
2. 해커가 데이터를 중간에 변조시켰다. -> 무결성 위반
3. 해커가 DDoS 공격 등으로 원활이 전송하지 못하게 하였다. -> 가용성 위반
3-2. CIA를 지키는 방법
1) Data를 보낼 때, 함께 데이터를 암호화하여 같이 보낸다.
-> 복호화할 수 있는 해커가 있다면 무용지물
2) Data를 보낼 때, 암호화하고 보낸다. (Key 사용해야 복호화 가능)
-> 해커가 열 수는 없지만, 실제 수령자도 Key 없이는 열 수 없다..
-> "Key 전달 문제 발생"
⬇️
일단은 문제는 있지만 2의 방식을 사용하면 ,
해커가 A의 메시지를 낚아채서 위조하는 문제는 해결할 수 있다.
그렇다면?
⬇️
예시 :
- A가 B에게 내일 10시에 보자고 보냈다.
- B의 입장에서는 ACK(OK Sign)를 받았다.
- 하지만, B는 나오지 않았다.
문제 상황의 2가지 이유 :
1) C가 A의 메시지를 낚아채서, 변형시켰을 수도 있다. (열쇠로 잠그면 1은 해결 가능하다고 했다.)
2) 혹은 C가 A의 메시지를 낚아채서 도착하지 못하게 한 뒤,
그냥 헛소리를 A가 보낸 것인 B에게 보내버릴 수 있다.
(메시지가 무엇인지는 모르지만 혼란스러운 메시지)
2) C가 A의 메시지를 낚아채서, B에게 도달하지 않았음에도 ACK를 보냈을 수도 있다.
"답장이 누구로부터 왔는지" 에 대한 문제
즉, "Key 전달 문제", "누구로부터 왔는지에 대한 문제" 2 가지만 해결하면 CIA를 지킬 수 있다!
4. RSA에 대해서
4-1. RSA
RSA(알앤샤)는 공개키 암호 시스템의 하나이다.
공개키(public key)와 비밀키(private key)를 사용하여 암호화에 사용되는 키 쌍을 생성하는 알고리즘이다.
공개키는 모두에게 공개되어 있으며, 누구나 이를 사용하여 메시지를 암호화할 수 있다. (암호화는 자유야~)
비밀키는 암호화된 메시지를 복호화하는 데 사용되며, 이 키는 소유자만이 알고 있어야 합니다.
RULE:
공개키로 암호화를 했다면, 개인키로만 열 수 있다. (Data 암호화에 자주 사용)
개인키로 암호화를 했다면, 공개키로만 열 수 있다. (전자 서명에 자주 사용 ; "나임을 인증")
4-2. Key 전달 문제 해결
RSA를 사용하여 A가 B에게 보낼 Data를 암호화 한다고 가정하자.
이제는 A가 B의 공개키로 암호화된 Data를 보내면, B의 비밀키로만 열 수 있게 된 것이다!!
(C는 가로채도 열 수가 없다 ㅠㅠ)
4-3. 누구로부터 왔는지에 대한 문제 해결
B는 A가 보냈다는 것도 확인해야 한다!
그렇다면, 이전에 B의 공개키로 암호화된 Data를 보낼 때, A의 개인키로 암호화를 한 번 더 시키는 것이다.
그럼 B는 A가 보낸 것인지를 A의 공개키로 확인할 수 있다.
B의 답장 또한 B의 개인키로 암호화하면 된다!
해당 RSA 알고리즘을 사용한 것이 JWT이다.
https://jinhos-devlog.tistory.com/entry/JWT%EB%9E%80
5. CORS에 대하여
<해당 포스트를 읽고 오길 바란다!>
JWT란?
0. 들어가기 전 https://jinhos-devlog.tistory.com/entry/Spring-Security-%EC%9B%B9-%EB%B3%B4%EC%95%88-%EC%9D%B4%ED%95%B4-JWT%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%A0%84 Spring Security 웹 보안 이해 : JWT를 이해하기 전 0. JWT란? J
jinhos-devlog.tistory.com
5-1. JWT의 토큰 인증 방식
세션을 사용했을 때의 문제점을 해결할 수 있다!
Cookie를 사용하지 않아도 된다! (쿠키 탈취의 취약점 사라짐 -> csrf 비활성화.)
JWT는 클라이언트가 서버에 인증된 상태를 유지하기 위해 사용될 때 일반적으로 쿠키를 사용하지 않는다는 말이다.
클라이언트 측은 다음 번 서버에 접근할 때 발급받은 Access Token을 들고 가야 하기 때문에,
이 토큰을 쿠키나, 세션 등에 저장할 수 있다.
서버를 분산시켜도 {🔑secret_key} 만 알고 있으면 된다!
조금 더 정확히 말하면, csrf에 대한 보호가 아예 필요 없다는 것이 아니다.
스프링 시큐리티에서는 기본적으로 csrf 토큰을 이용해서 방어를 하고 있다.
매 요청마다 csrf 토큰은 서버에서 임의의 난수를 생성하여 클라이언트에게 넘겨주는 방식이다.
클라이언트는 서버로 요청할 때 발급받은 csrf 토큰과 함께 Request를 보내면 서버에서는 csrf 토큰을 비교하여 위조된 요청인지 판별하게 되는 것이다.
브라우저에서 보내는 요청은 세션 쿠키를 포함하는 모든 쿠키를 자동으로 포함하기 때문에 CSRF 공격이 가능할 수 있다!
그렇기 때문에, 쿠키 탈취의 취약점이 있다는 것이다 !!!
csrf.disable(); -> JWT 토큰 사용
+ 마지막으로 추가...
그렇다면 JWT 토큰이 CSRF 공격 자체를 막을 수 있다는 것인가?
JWT는 보안 공격을 막기 위한 것이 주 목적이 아니기 때문에 모든 보안 관련 상황에서 충분하지 않을 수 있다.
JWT 토큰을 Local Storage에 토큰을 저장하고 bearer token으로 사용한다면 CSRF 공격에 대한 대응은 될 수 있다만, XSS 공격에는 취약할 수 있다.
.... 이야기가 너무 길어진다.
어쨌든 다양한 방법으로 보안 공격을 방지하는 메커니즘을 구현하고 관리할 필요성이 있다는 것.
5-2. 여러 도메인에서의 Session/Cookie !?
1) 기본 구조

2) 도메인이 여러 개라면?
<도메인 간(Cross-Origin)에서의 쿠키 전송에 관한 내용>
... CORS
아까 서버를 여러 개 두었을 때의 단점도 이야기 했다! -> 이것도 해결 가능하다
5-3. CORS(Cross-Origin Resource Sharing)

간단히 말하면 이런 것이다.
웹 페이지에서 실행 중인 스크립트가
다른 출처의 자원에 접근할 수 있도록
브라우저에게 허용하는 보안 기능
브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)를 따르기 때문에,
한 출처에서 불러온 웹 페이지가 다른 출처의 자원에 접근하는 것을 제한한다.
* 쉽게 말해, 도메인이 다른 서버로 리소스 요청을 보내면, 쿠키를 전송시키지 않는다!
* 다른 도메인으로의 리다이렉션외에도
javascript에서 외부 도메인에서의 AJAX 요청에서 브라우저가 쿠키를 전송하지 않을 수 있다.
해결방법
CORS는 이러한 보안 정책으로 인해 발생하는 문제를 해결하기 위해 도입되었다.
CORS는 웹 브라우저에서 다른 출처의 리소스에 안전하게 접근할 수 있도록 허용하는 보안 메커니즘이다.
- CORS 정책에 따라 브라우저는 보안상의 이유로 다른 도메인으로의 AJAX 요청 시에는 쿠키를 자동으로 전송하지 않는다고 했다.
- 그러나, JavaScript 코드에서 직접 XMLHttpRequest 또는 Fetch API를 사용하여 AJAX 요청을 보낼 때는 이러한 제약이 적용되지 않을 수 있다. ("HTTP Only = False" 로 풀어준다면.)
fetch("http://www.naver.com", {
headers: {
Cookie: "~~"
}
}).then();
- 즉, JavaScript 코드에서 직접 조작하면서 요청 헤더에 쿠키를 추가하여 보낼 수 있다.
- 이 경우에는 브라우저의 보안 정책(CORS)를 우회하는 것이므로, 신뢰할 수 없는 도메인으로부터의 요청에 대한 쿠키 전송을 막기 위해 "HTTP Only = False" 로 풀지 않고 True로 설정하는 편이다.
<외부 장난질 가능해짐.. 보안성 DOWN>
=> headers에 Anthorization를 사용하는 방식!
6. Basic / Bearer Authentication
6-1. Basic Authentication
- 타입(Type): Basic
- 토큰 형식(Credentials): Base64로 인코딩된 사용자 ID와 비밀번호
- 보안 취약성: Basic 토큰은 사용자 ID와 비밀번호가 Base64로 인코딩(RFC 7617)
토큰이 노출되면 사용자의 인증 정보가 노출 가능 -> 보안에 취약 - 사용 예시:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- Basic Authentication은 브라우저가 제공하는 기본 인증 팝업이나 HTTP 클라이언트 라이브러리를 통해 쉽게 사용할 수 있다.
6-2. Bearer Token
- 타입(Type): Bearer
- 토큰 형식(Credentials): 주로 JWT(RFC 7519) 또는 OAuth 토큰(RFC 6750) 사용
- 보안 취약성: Bearer 토큰은 토큰에 ID와 PW를 내장하지 않기 때문에 기본적으로 Basic 보다는 보안적으로 강력합니다.
- 사용 예시:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- 서버는 세션 저장소가 필요 없고, (여러 개의 서버를 둬도 상관 없다는 말!!!)
토큰 자체에 사용자 정보가 포함되어 있어 STATELESS하며,
무결성과 보안성이 강조되는 특징이 있다!
0. JWT란?
JWT(JSON Web Token)는 정보를 안전하게 전송하기 위한 간단한 토큰 기반의 오픈 표준이다.
Header(헤더), Payload(페이로드), Signature(서명) 세 부분으로 구성되어 있으며........... 는 잠시 제쳐두고!!
JWT가 어떻게 쓰고, 어떻게 생겼는지. 보다는
"왜 사용되고, 어디에 사용하는지"가 더욱 중요하다!!!
항상 공부를 할 때, 블로그에서 긁어와서 코드를 돌아가게 만드는 것은 의미가 없다고 생각하는 편이다.
근본적으로 왜 사용되고, 어디에 사용되고, 그 이후에 어떻게 사용하는지를 배우는 서순이 맞다고 생각한다.
1. Session에 대해서
세션(Session)은 웹 애플리케이션에서 클라이언트와 서버 간의 지속적인 상태를 유지하기 위한 메커니즘이다.
HTTP 프로토콜은 기본적으로 상태를 유지하지 않는(stateless) 프로토콜이다!
즉, "상태를 기억할 수 없는 금붕어 같은 친구"라는 것이다...
클라이언트의 각 요청은 서버에 의해 완전히 독립적으로 처리된다.
하지만 세션을 사용하면 클라이언트의 여러 요청 간에 상태를 공유할 수 있다.
만약에 해당 client가 server에 방문한 적이 있는지!? 에 관한 이야기라면,
아주 간단한 방법으로, Session에 "방문한 적 있음 카드"를 작성해서 client에게 Response와 함께 주면 된다.
그리고 "너 다음에 방문할 때는 이거 들고와!"라는 방식을 쓰는 것이다.
1-1. 클라이언트가 서버에 최초 접근한 경우

1-2. Request Header에 Session ID를 들고 접근한 경우

1-3. Session이 사라지는 경우
1) 서버 측에서 Session을 강제로 지우는 경우
2) 사용자가 브라우저를 종료할 때
3) Session 만료 시간이 지났을 때 (보통 30분)
1-4. 보통 Session이 사용되는 로그인 요청 & 인증
Session ID : 1234는 (이미 접근한 계정)
Session ID : 3456은 최초 접근 계정이라고 가정하자.
- 1 ~ 4 : 최초 접근
- 5 ~ 10 : 로그인

- 이후 "user 정보가 필요한 페이지" 요청

* 정리
민감한 정보를 요청할 경우,
요청 헤더에 있는 Session ID를 확인해서 / 해당 User인지를 판별하고
필요한 정보를 제공해준다.
1-5. Session의 단점
Client가 몇 백 만명 이라면....?
동시 접속자 수가 서버가 처리할 수 있는 인원이 넘어버리면..?
-> 나머지는 모두 대기ㅠㅠ
=> 자주 사용하는 해결책이 "서버를 여러개 두는 것 ; Load Balancing"
그런데 문제는 여기서 발생한다.
서버를 여러개 두면, Session 저장소도 각각 따로 두게 된다는 점
1번 서버에 첫 요청을 보내놓고, 2번 서버에서 재요청을 하게 되면,
2번 서버는 해당 Client를 처음 온 친구로 인식하게 된다는 점.

1-6. 해결책
- Sticky Session을 이용해 그 사용자가 갔던 서버로만 보내는 것이다.
- 모든 서버에 세션이 생성 될 때마다 세션을 복제 시킨다. (동기화)
- DB에 세션 정보를 저장한다. (DB에는 IO가 일어나기 때문에 속도가 엄청나게 저하..)
-> 세션 사용의 장점을 파괴ㅋㅋ
메모리 공유 서버 (RAM)를 이용한다! (주로 Redis를 사용) - JWT를 사용하면 이 문제들을 해결 할 수 있다.
2. TCP에 대해서
컴퓨터 네트워크의 내용이다... 컴공생들은 아는 내용 ㅠ 간단하게 하고 넘어가겠다!
2-1. OSI 7계층

- 4번 째인 Transport 계층에서 TCP/UDP 통신 여부를 결정한다.
2-2. TCP/UDP
1) TCP (Transmission Control Protocol):
신뢰성: TCP는 연결 기반의 프로토콜로, 데이터 전송 시 신뢰성을 중요시 한다!
데이터가 전송되면 수신 측에서 확인 응답(ACK)을 보내고, 만약 손실이나 오류가 발생하면 재전송을 수행!
순서 보장: TCP는 데이터의 전송 순서를 보장한다.
흐름 제어와 혼잡 제어
연결 지향
속도 매우 느림
2) UDP (User Datagram Protocol):
신뢰성: UDP는 비연결성 프로토콜로, 신뢰성이 TCP보다 낮다. 오류가 발생하면 복구나 재전송이 이루어지지 않는다.
순서 보장 없음: UDP는 데이터의 순서를 보장하지 않는다.
흐름 제어와 혼잡 제어 없음
연결 지향이 아님
빠른 전송 속도 : 실시간에 자주 쓰임
-> 우리 웹은 TCP/IP 통신을 한다!
3. CIA에 대해서 (보안)
3-1. CIA
CIA는 정보 보안의 기본 원칙을 나타내는 약어이다.
각각 Confidentiality(기밀성), Integrity(무결성), Availability(가용성)을 나타낸다.
데이터/ 네트워크 보안 등에서 매우 자주 들어본 단어들일 것이다.
1) Confidentiality (기밀성):
정의: 기밀성은 정보에 대한 무단 접근을 방지, 오직 허가된 사용자나 시스템만이 해당 정보에 접근할 수 있도록 하는 원칙
목표: 민감한 정보가 무단으로 노출되는 것을 방지하여 정보의 비밀성을 유지한다.
2) Integrity (무결성):
정의: 무결성은 정보가 정확하고 변조되지 않았음을 보장하는 원칙이다.
목표: 정보가 변경되거나 조작되지 않도록 하여 데이터의 신뢰성을 보장한다.
3) Availability (가용성):
정의: 가용성은 정보나 시스템이 필요할 때 항상 사용 가능한 상태를 유지하는 원칙이다.
즉, 서비스의 지속적인 이용이 보장되어야 한다.
목표: 서비스 중단을 최소화하고 사용자가 필요할 때 항상 정보나 서비스에 접근 가능하도록 해야 한다.
---
쉽게 말해서, A -> B 로 데이터를 전송한다고 해보자.
1. 해커가 데이터를 중간에 빼돌렸다. -> 기밀성 위반
2. 해커가 데이터를 중간에 변조시켰다. -> 무결성 위반
3. 해커가 DDoS 공격 등으로 원활이 전송하지 못하게 하였다. -> 가용성 위반
3-2. CIA를 지키는 방법
1) Data를 보낼 때, 함께 데이터를 암호화하여 같이 보낸다.
-> 복호화할 수 있는 해커가 있다면 무용지물
2) Data를 보낼 때, 암호화하고 보낸다. (Key 사용해야 복호화 가능)
-> 해커가 열 수는 없지만, 실제 수령자도 Key 없이는 열 수 없다..
-> "Key 전달 문제 발생"
⬇️
일단은 문제는 있지만 2의 방식을 사용하면 ,
해커가 A의 메시지를 낚아채서 위조하는 문제는 해결할 수 있다.
그렇다면?
⬇️
예시 :
- A가 B에게 내일 10시에 보자고 보냈다.
- B의 입장에서는 ACK(OK Sign)를 받았다.
- 하지만, B는 나오지 않았다.
문제 상황의 2가지 이유 :
1) C가 A의 메시지를 낚아채서, 변형시켰을 수도 있다. (열쇠로 잠그면 1은 해결 가능하다고 했다.)
2) 혹은 C가 A의 메시지를 낚아채서 도착하지 못하게 한 뒤,
그냥 헛소리를 A가 보낸 것인 B에게 보내버릴 수 있다.
(메시지가 무엇인지는 모르지만 혼란스러운 메시지)
2) C가 A의 메시지를 낚아채서, B에게 도달하지 않았음에도 ACK를 보냈을 수도 있다.
"답장이 누구로부터 왔는지" 에 대한 문제
즉, "Key 전달 문제", "누구로부터 왔는지에 대한 문제" 2 가지만 해결하면 CIA를 지킬 수 있다!
4. RSA에 대해서
4-1. RSA
RSA(알앤샤)는 공개키 암호 시스템의 하나이다.
공개키(public key)와 비밀키(private key)를 사용하여 암호화에 사용되는 키 쌍을 생성하는 알고리즘이다.
공개키는 모두에게 공개되어 있으며, 누구나 이를 사용하여 메시지를 암호화할 수 있다. (암호화는 자유야~)
비밀키는 암호화된 메시지를 복호화하는 데 사용되며, 이 키는 소유자만이 알고 있어야 합니다.
RULE:
공개키로 암호화를 했다면, 개인키로만 열 수 있다. (Data 암호화에 자주 사용)
개인키로 암호화를 했다면, 공개키로만 열 수 있다. (전자 서명에 자주 사용 ; "나임을 인증")
4-2. Key 전달 문제 해결
RSA를 사용하여 A가 B에게 보낼 Data를 암호화 한다고 가정하자.
이제는 A가 B의 공개키로 암호화된 Data를 보내면, B의 비밀키로만 열 수 있게 된 것이다!!
(C는 가로채도 열 수가 없다 ㅠㅠ)
4-3. 누구로부터 왔는지에 대한 문제 해결
B는 A가 보냈다는 것도 확인해야 한다!
그렇다면, 이전에 B의 공개키로 암호화된 Data를 보낼 때, A의 개인키로 암호화를 한 번 더 시키는 것이다.
그럼 B는 A가 보낸 것인지를 A의 공개키로 확인할 수 있다.
B의 답장 또한 B의 개인키로 암호화하면 된다!
해당 RSA 알고리즘을 사용한 것이 JWT이다.
https://jinhos-devlog.tistory.com/entry/JWT%EB%9E%80
5. CORS에 대하여
<해당 포스트를 읽고 오길 바란다!>
JWT란?
0. 들어가기 전 https://jinhos-devlog.tistory.com/entry/Spring-Security-%EC%9B%B9-%EB%B3%B4%EC%95%88-%EC%9D%B4%ED%95%B4-JWT%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%A0%84 Spring Security 웹 보안 이해 : JWT를 이해하기 전 0. JWT란? J
jinhos-devlog.tistory.com
5-1. JWT의 토큰 인증 방식
세션을 사용했을 때의 문제점을 해결할 수 있다!
Cookie를 사용하지 않아도 된다! (쿠키 탈취의 취약점 사라짐 -> csrf 비활성화.)
JWT는 클라이언트가 서버에 인증된 상태를 유지하기 위해 사용될 때 일반적으로 쿠키를 사용하지 않는다는 말이다.
클라이언트 측은 다음 번 서버에 접근할 때 발급받은 Access Token을 들고 가야 하기 때문에,
이 토큰을 쿠키나, 세션 등에 저장할 수 있다.
서버를 분산시켜도 {🔑secret_key} 만 알고 있으면 된다!
조금 더 정확히 말하면, csrf에 대한 보호가 아예 필요 없다는 것이 아니다.
스프링 시큐리티에서는 기본적으로 csrf 토큰을 이용해서 방어를 하고 있다.
매 요청마다 csrf 토큰은 서버에서 임의의 난수를 생성하여 클라이언트에게 넘겨주는 방식이다.
클라이언트는 서버로 요청할 때 발급받은 csrf 토큰과 함께 Request를 보내면 서버에서는 csrf 토큰을 비교하여 위조된 요청인지 판별하게 되는 것이다.
브라우저에서 보내는 요청은 세션 쿠키를 포함하는 모든 쿠키를 자동으로 포함하기 때문에 CSRF 공격이 가능할 수 있다!
그렇기 때문에, 쿠키 탈취의 취약점이 있다는 것이다 !!!
csrf.disable(); -> JWT 토큰 사용
+ 마지막으로 추가...
그렇다면 JWT 토큰이 CSRF 공격 자체를 막을 수 있다는 것인가?
JWT는 보안 공격을 막기 위한 것이 주 목적이 아니기 때문에 모든 보안 관련 상황에서 충분하지 않을 수 있다.
JWT 토큰을 Local Storage에 토큰을 저장하고 bearer token으로 사용한다면 CSRF 공격에 대한 대응은 될 수 있다만, XSS 공격에는 취약할 수 있다.
.... 이야기가 너무 길어진다.
어쨌든 다양한 방법으로 보안 공격을 방지하는 메커니즘을 구현하고 관리할 필요성이 있다는 것.
5-2. 여러 도메인에서의 Session/Cookie !?
1) 기본 구조

2) 도메인이 여러 개라면?
<도메인 간(Cross-Origin)에서의 쿠키 전송에 관한 내용>
... CORS
아까 서버를 여러 개 두었을 때의 단점도 이야기 했다! -> 이것도 해결 가능하다
5-3. CORS(Cross-Origin Resource Sharing)

간단히 말하면 이런 것이다.
웹 페이지에서 실행 중인 스크립트가
다른 출처의 자원에 접근할 수 있도록
브라우저에게 허용하는 보안 기능
브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)를 따르기 때문에,
한 출처에서 불러온 웹 페이지가 다른 출처의 자원에 접근하는 것을 제한한다.
* 쉽게 말해, 도메인이 다른 서버로 리소스 요청을 보내면, 쿠키를 전송시키지 않는다!
* 다른 도메인으로의 리다이렉션외에도
javascript에서 외부 도메인에서의 AJAX 요청에서 브라우저가 쿠키를 전송하지 않을 수 있다.
해결방법
CORS는 이러한 보안 정책으로 인해 발생하는 문제를 해결하기 위해 도입되었다.
CORS는 웹 브라우저에서 다른 출처의 리소스에 안전하게 접근할 수 있도록 허용하는 보안 메커니즘이다.
- CORS 정책에 따라 브라우저는 보안상의 이유로 다른 도메인으로의 AJAX 요청 시에는 쿠키를 자동으로 전송하지 않는다고 했다.
- 그러나, JavaScript 코드에서 직접 XMLHttpRequest 또는 Fetch API를 사용하여 AJAX 요청을 보낼 때는 이러한 제약이 적용되지 않을 수 있다. ("HTTP Only = False" 로 풀어준다면.)
fetch("http://www.naver.com", {
headers: {
Cookie: "~~"
}
}).then();
- 즉, JavaScript 코드에서 직접 조작하면서 요청 헤더에 쿠키를 추가하여 보낼 수 있다.
- 이 경우에는 브라우저의 보안 정책(CORS)를 우회하는 것이므로, 신뢰할 수 없는 도메인으로부터의 요청에 대한 쿠키 전송을 막기 위해 "HTTP Only = False" 로 풀지 않고 True로 설정하는 편이다.
<외부 장난질 가능해짐.. 보안성 DOWN>
=> headers에 Anthorization를 사용하는 방식!
6. Basic / Bearer Authentication
6-1. Basic Authentication
- 타입(Type): Basic
- 토큰 형식(Credentials): Base64로 인코딩된 사용자 ID와 비밀번호
- 보안 취약성: Basic 토큰은 사용자 ID와 비밀번호가 Base64로 인코딩(RFC 7617)
토큰이 노출되면 사용자의 인증 정보가 노출 가능 -> 보안에 취약 - 사용 예시:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- Basic Authentication은 브라우저가 제공하는 기본 인증 팝업이나 HTTP 클라이언트 라이브러리를 통해 쉽게 사용할 수 있다.
6-2. Bearer Token
- 타입(Type): Bearer
- 토큰 형식(Credentials): 주로 JWT(RFC 7519) 또는 OAuth 토큰(RFC 6750) 사용
- 보안 취약성: Bearer 토큰은 토큰에 ID와 PW를 내장하지 않기 때문에 기본적으로 Basic 보다는 보안적으로 강력합니다.
- 사용 예시:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- 서버는 세션 저장소가 필요 없고, (여러 개의 서버를 둬도 상관 없다는 말!!!)
토큰 자체에 사용자 정보가 포함되어 있어 STATELESS하며,
무결성과 보안성이 강조되는 특징이 있다!