728x90
반응형
SMALL
JWT (JSON Web Token)의 사용과 보안 고려 사항
JWT는 인증 및 정보를 안전하게 전송하기 위해 사용되는 JSON 기반의 토큰입니다. 클라이언트와 서버 간 인증 및 데이터 교환을 간편하게 처리할 수 있습니다.
1. JWT란?
정의
- JWT는 클라이언트와 서버 간에 정보를 JSON 형식으로 안전하게 주고받기 위한 토큰입니다.
- 토큰 자체에 데이터를 포함하고, 서명을 통해 무결성을 보장합니다.
구조
JWT는 세 부분으로 구성되며, .
으로 구분됩니다:
- Header (헤더): 토큰 타입(JWT)과 암호화 알고리즘 정보를 포함.
- Payload (페이로드): 토큰에 담길 데이터(예: 사용자 ID, 권한).
- Signature (서명): 토큰의 무결성을 검증하기 위한 암호화된 서명.
JWT 예시:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywiYWRtaW4iOnRydWV9.sflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
2. JWT의 주요 사용 사례
- 사용자 인증 (Authentication)
- 클라이언트가 서버에서 인증을 완료하면, 서버는 JWT를 발급.
- 이후 요청마다 JWT를 포함해 인증을 대체.
- 예: 로그인 후 발급된 JWT로 API 호출.
- 정보 전달
- JWT는 클라이언트와 서버 간에 데이터를 전달하는 간편한 방법.
- 예: 사용자의 역할(Role), 만료 시간(Exp) 등 포함.
- API 인증
- RESTful API와 같은 무상태(State-less) 환경에서 인증에 사용.
- 각 요청에 JWT를 포함시켜 서버가 상태를 저장하지 않아도 됨.
- 싱글 사인온 (SSO)
- 하나의 로그인으로 여러 시스템에 접근 가능.
- JWT는 로그인 정보를 공유하는 데 사용.
3. JWT의 보안 고려 사항
3.1. 토큰 보호
- 비밀키 관리
- 서명을 생성할 때 사용하는 비밀키는 절대 노출되어선 안 됨.
- 안전한 키 저장소 사용.
- HTTPS 사용
- 네트워크에서 데이터가 노출되지 않도록 항상 HTTPS를 통해 전송.
- 토큰 저장소 보안
- 로컬 스토리지 또는 쿠키에 토큰을 저장할 때 보안 설정 필요.
- 쿠키의 경우
HttpOnly
,Secure
플래그 사용.
3.2. 만료 시간 설정
- 짧은 만료 시간
- 토큰의 수명을 짧게 설정하여 유효하지 않은 토큰이 악용되지 않도록 방지.
- 예:
exp
클레임을 설정.
- 갱신 메커니즘
- 만료된 토큰을 새로 발급받을 수 있는 갱신 기능 제공(예: Refresh Token).
3.3. 토큰 내용
- 민감 정보 저장 금지
- JWT는 디코딩이 쉽기 때문에 민감 정보를 포함하면 안 됨.
- 예: 비밀번호, 카드 정보 등.
- 최소한의 데이터만 포함
- 필요한 정보만 토큰에 담아 크기를 줄이고 보안 리스크 최소화.
3.4. 서명 알고리즘
- 안전한 알고리즘 사용
HS256
(HMAC SHA-256),RS256
(RSA SHA-256) 등 검증된 알고리즘 사용.none
알고리즘을 절대 사용하지 않음.
- 공개키/개인키 관리
- 비대칭키 알고리즘(RSA 등)을 사용하는 경우 키 관리를 철저히.
3.5. 재생 공격 방지
- 토큰 재사용 방지
- 토큰을 서버에서 블랙리스트에 추가하여 무효화.
- 예: 중요한 작업 이후 토큰 강제 만료 처리.
- Nonce 값 사용
- 고유 식별자(Nonce)를 추가하여 각 요청의 고유성을 보장.
4. 용어 설명
용어 | 설명 |
---|---|
JWT (JSON Web Token) | 클라이언트와 서버 간 데이터를 안전하게 주고받기 위해 사용하는 토큰. |
Header (헤더) | JWT의 첫 번째 부분으로, 토큰 정보(타입, 암호화 방식)를 포함. |
Payload (페이로드) | JWT의 두 번째 부분으로, 실제 데이터를 담고 있음. 예: 사용자 ID, 권한 정보. |
Signature (서명) | JWT의 마지막 부분으로, 헤더와 페이로드의 무결성을 검증하기 위한 암호화된 서명. |
HMAC (Hash-based Message Authentication Code) | 메시지의 무결성을 보장하기 위해 사용되는 암호화 방법. |
Refresh Token | JWT 만료 시 새 토큰을 발급받기 위해 사용하는 장기 유효 토큰. |
HTTPS | 데이터를 암호화하여 안전하게 전송하기 위한 웹 통신 프로토콜. |
Nonce (랜덤 값) | 각 요청의 고유성을 보장하기 위해 사용되는 임시 랜덤 값. |
5. HTML 예제
5.1. JWT 저장과 전송
<!-- HTML: 사용자 로그인 후 JWT 저장 -->
<script>
// 로그인 요청 후 JWT를 로컬 스토리지에 저장
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
localStorage.setItem("jwt", token);
// API 호출 시 JWT를 Authorization 헤더에 추가
fetch("https://api.example.com/protected-data", {
method: "GET",
headers: {
"Authorization": `Bearer ${localStorage.getItem("jwt")}`
}
}).then(response => {
if (response.ok) return response.json();
throw new Error("Unauthorized");
}).then(data => {
console.log("Protected Data:", data);
}).catch(err => {
console.error(err.message);
});
</script>
5.2. 서버에서 JWT 생성과 검증
Node.js 예제 (Express.js):
const jwt = require('jsonwebtoken');
// 비밀키
const SECRET_KEY = "supersecretkey";
// JWT 생성
function generateToken(user) {
return jwt.sign(
{ id: user.id, role: user.role },
SECRET_KEY,
{ expiresIn: '1h' } // 1시간 만료
);
}
// JWT 검증
function verifyToken(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).send("Access Denied");
try {
const verified = jwt.verify(token, SECRET_KEY);
req.user = verified; // 사용자 정보 저장
next();
} catch (err) {
res.status(400).send("Invalid Token");
}
}
6. 요약
- JWT 사용: 인증, 정보 전달, API 인증 등에 사용.
- 보안 고려 사항
- 민감 정보 포함 금지.
- HTTPS를 통한 전송.
- 짧은 만료 시간 설정.
- 안전한 서명 알고리즘 사용.
- 실제 구현
- 클라이언트에서는 토큰을 안전하게 저장 및 전송.
- 서버에서는 토큰 검증 및 무효화 메커니즘 제공.
반응형
SMALL
'보안' 카테고리의 다른 글
로드 밸런싱의 필요성 : 쉬운설명 (0) | 2024.12.10 |
---|---|
인증(Authentication)과 인가(Authorization)의 차이점 (0) | 2024.12.08 |
XSS(Cross-Site Scripting)와 CSRF(Cross-Site Request Forgery)의 차이점과 방어 방법 (1) | 2024.12.08 |
SSL/TLS의 역할과 동작 방식 (0) | 2024.12.08 |
대칭키와 비대칭키 암호화의 차이점 (0) | 2024.12.08 |