JWT Encoder
HS256, HS384, HS512로 JSON 웹 토큰 생성 및 서명
헤더
페이로드
비밀 키
인코딩된 JWT
비밀 키는 브라우저를 벗어나지 않습니다. 모든 서명은 클라이언트 측에서 수행됩니다.
JWT 인코딩이란?
JWT 인코딩은 JSON Web Token을 생성하는 프로세스입니다——암호화 키로 서명된 클레임 집합을 담은 컴팩트하고 URL 안전한 문자열입니다. 결과는 RFC 7519로 정의된 3부 토큰(헤더.페이로드.서명)으로, 서버는 세션 상태를 유지하지 않고 검증할 수 있습니다. 온라인 JWT 인코딩을 사용하면 테스트 및 개발을 위해 브라우저에서 직접 토큰을 생성하고 서명할 수 있습니다.
헤더는 서명 알고리즘(예: HS256) 및 토큰 유형을 선언합니다. 페이로드는 클레임을 포함합니다——주체(sub), 만료 시간(exp), 애플리케이션이 필요로 하는 사용자 정의 데이터 등 키-값 쌍입니다. 두 부분 모두 JSON으로 직렬화된 다음 base64url로 인코딩됩니다. 서명은 비밀 키를 사용하여 인코딩된 헤더와 페이로드 위에서 계산되어 3개 세그먼트를 바인딩합니다.
세션 쿠키와 달리 JWT는 자체 포함되어 있습니다. 검증자는 데이터베이스를 쿼리하거나 외부 서비스를 호출할 필요가 없습니다. 이로 인해 JWT 기반 인증은 REST API, 마이크로서비스, 단일 페이지 애플리케이션에서 인기가 있으며, 상태 비저장 권한 부여는 지연 시간을 줄이고 수평 확장을 단순화합니다.
JWT 인코더를 사용하는 이유는?
JWT를 수동으로 생성하려면 base64url 인코딩, JSON 직렬화, HMAC 계산이 필요합니다. 이 도구는 3가지 단계를 즉시 처리하므로 올바른 클레임에 집중할 수 있습니다.
JWT 인코더 사용 사례
HS256 vs HS384 vs HS512: HMAC 알고리즘 비교
3개 알고리즘 모두 공유 비밀을 사용하여 HMAC(해시 기반 메시지 인증 코드)를 사용합니다. 차이점은 기본 해시 함수에 있으며, 이는 서명 길이와 보안 여유도에 영향을 미칩니다. 대부분의 애플리케이션의 경우 HS256은 충분한 보안을 제공합니다. 규정 준수 요구 사항(예: FIPS-140)이 더 강력한 해시를 요구하거나 토큰이 높은 가치의 권한 부여 결정을 수행할 때 HS384 또는 HS512를 선택합니다.
| 알고리즘 | 해시 | 서명 | 속도 | 일반적 사용 |
|---|---|---|---|---|
| HS256 | SHA-256 | 32 B | Fastest | General purpose, default for most libraries |
| HS384 | SHA-384 | 48 B | Fast | Higher security margin, FIPS-140 compliant |
| HS512 | SHA-512 | 64 B | Fast | Maximum HMAC security, large payloads |
표준 JWT 클레임 참조
RFC 7519는 7개의 등록된 클레임을 정의합니다. 어느 것도 필수는 아니지만 올바르게 사용하면 상호 운용성과 보안이 향상됩니다. exp 클레임은 특히 중요합니다——만료 없는 토큰은 비밀이 로테이션되지 않으면 무기한 유효합니다.
| 클레임 | 이름 | 설명 | 예제 |
|---|---|---|---|
| iss | Issuer | Who issued the token | "auth.example.com" |
| sub | Subject | Who the token represents | "user-123" |
| aud | Audience | Intended recipient service | "api.example.com" |
| exp | Expiration | Unix timestamp — token invalid after this time | 1717203600 |
| nbf | Not Before | Unix timestamp — token invalid before this time | 1717200000 |
| iat | Issued At | Unix timestamp when the token was created | 1717200000 |
| jti | JWT ID | Unique token identifier for revocation tracking | "a1b2c3d4" |
코드의 JWT 인코딩
이 예제들은 프로그래밍 방식으로 JWT를 생성하고 서명하는 방법을 보여줍니다. 각 스니펫은 유효한 HS256 서명 토큰을 생성합니다. 프로덕션 시스템의 경우 항상 exp 클레임을 설정하고 최소 256비트의 암호적으로 안전한 비밀을 사용합니다.
async function signJWT(payload, secret, alg = 'HS256') {
const header = { alg, typ: 'JWT' }
const enc = new TextEncoder()
// Base64url encode header and payload
const b64url = (obj) =>
btoa(JSON.stringify(obj)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
const h = b64url(header)
const p = b64url(payload)
// Sign with HMAC-SHA256
const key = await crypto.subtle.importKey(
'raw', enc.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
)
const sig = await crypto.subtle.sign('HMAC', key, enc.encode(`${h}.${p}`))
const s = btoa(String.fromCharCode(...new Uint8Array(sig)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
return `${h}.${p}.${s}`
}
// Usage
const token = await signJWT(
{ sub: 'user-123', name: 'Alice', iat: Math.floor(Date.now() / 1000) },
'your-256-bit-secret'
)
// → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."import jwt
import time
payload = {
"sub": "user-123",
"name": "Alice",
"iat": int(time.time()),
"exp": int(time.time()) + 3600, # expires in 1 hour
}
# Sign with HS256 (default)
token = jwt.encode(payload, "your-256-bit-secret", algorithm="HS256")
# → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."
# Verify and decode
decoded = jwt.decode(token, "your-256-bit-secret", algorithms=["HS256"])
# → {"sub": "user-123", "name": "Alice", "iat": 1717200000, "exp": 1717203600}const jwt = require('jsonwebtoken')
const payload = {
sub: 'user-123',
name: 'Alice',
role: 'admin',
}
// Sign — iat is added automatically
const token = jwt.sign(payload, 'your-256-bit-secret', {
algorithm: 'HS256',
expiresIn: '1h', // sets exp claim
issuer: 'auth.example.com', // sets iss claim
})
// Verify
const decoded = jwt.verify(token, 'your-256-bit-secret')
// → { sub: 'user-123', name: 'Alice', role: 'admin', iat: ..., exp: ... }package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
func main() {
claims := jwt.MapClaims{
"sub": "user-123",
"name": "Alice",
"iat": time.Now().Unix(),
"exp": time.Now().Add(time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, _ := token.SignedString([]byte("your-256-bit-secret"))
fmt.Println(signed)
// → eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOi...
}