간단하면서도 안전한 인증 토큰 만들기 (Python, HMAC, ID/SECRET 기반)
🔐 간단하면서도 안전한 인증 토큰 만들기 (Python, HMAC, ID/SECRET 기반)
날짜: 2025-06-07
API 서버 간의 안전한 통신이나 임시 인증이 필요할 때 사용할 수 있는 HMAC 기반의 간단한 토큰 생성 로직을 소개합니다.
이 방식은 ID + SECRET + TIMESTAMP 조합으로 생성된 토큰을 이용하여, 수신 측에서는 동일한 알고리즘으로 토큰을 검증할 수 있습니다.
✅ HMAC 인증이란?
- HMAC은 Hash-based Message Authentication Code의 약자입니다.
- 공유된 **비밀 키(SECRET_KEY)**를 이용해, 변조나 위조 없이 메시지의 무결성을 검증할 수 있습니다.
- 타임스탬프 기반 유효기간 제한도 손쉽게 추가 가능하므로, 인증 토큰 용도로 적합합니다.
🧩 토큰 생성 및 검증 모듈 (auth_token.py)
# auth_token.py
import hmac
import hashlib
import time
class AuthToken:
def __init__(self, client_id: str, client_secret: str, hash_algo: str = 'sha256', valid_window: int = 3):
"""
인증 토큰 생성기 초기화
Args:
client_id (str): 클라이언트 식별자 (예: 'my-client')
client_secret (str): 클라이언트 비밀 키 (HMAC 서명용)
hash_algo (str): 사용할 해시 알고리즘 (기본값: 'sha256')
valid_window (int): 토큰 유효 시간(초 단위, 기본값: 3초)
"""
self.client_id = client_id
self.secret_key = client_secret.encode()
self.hash_algo = getattr(hashlib, hash_algo)
self.valid_window = valid_window
def generate(self, timestamp: int = None) -> str:
if timestamp is None:
timestamp = int(time.time())
raw = f"{self.client_id}.{timestamp}"
signature = hmac.new(self.secret_key, raw.encode(), self.hash_algo).hexdigest()
return f"{self.client_id}:{timestamp}:{signature}"
def verify(self, token: str) -> bool:
try:
parts = token.split(":")
if len(parts) != 3:
return False
token_id, token_ts, token_sig = parts
if token_id != self.client_id:
return False
token_ts = int(token_ts)
now = int(time.time())
if abs(now - token_ts) > self.valid_window:
return False
expected_token = self.generate(token_ts)
return hmac.compare_digest(token, expected_token)
except Exception:
return False
🧪 사용 예시
from auth_token import AuthToken
auth = AuthToken(client_id="example-client", client_secret="shared_secret")
# 1. 서버에서 토큰 생성
token = auth.generate()
print("🔐 Generated:", token)
# 2. 다른 서버 또는 수신 측에서 토큰 검증
is_valid = auth.verify(token)
print("✅ Valid:", is_valid)
📌 특징 요약
- 독립적인 모듈로 설계되어 어떤 웹 프레임워크와도 함께 사용 가능
SECRET_KEY기반 HMAC 토큰으로 변조 위험 최소화timestamp기반 유효기간 설정으로 재사용 방지hmac.compare_digest()를 사용해 타이밍 공격 방어- 타이밍 공격 이란, 일반 문자열 비교의 경우 앞글자부터 순차적으로 비교하다가 실패시 리턴하는데
- 이때 일치 문자열이 있으면 아주 미미하게 응답속도 차이가 생기고 이것을 공격자가 이용하여 전체 토큰 문자열을 유추해내는 것
🧠 활용 팁
- API 요청 헤더에
X-Auth-Token형식으로 포함시키면 좋습니다. - 클라이언트에 발급된
client_id+secret_key를 미리 등록해두고 검증하는 방식으로 확장 가능합니다. - 토큰 유효기간을 짧게 유지하면 실시간 보안 수준을 높일 수 있습니다.
✅ HMAC 인증 토큰의 실제 사용 사례
- HMAC 기반 인증 토큰은 많은 IT 회사에서 실제로 널리 사용됩니다.
- 다만 JWT, OAuth, API Key 같은 다른 방식들과 용도나 보안 수준에 따라 선택적으로 사용되는 경우가 많습니다.
-
서버 간 통신 (서버 → 서버)
- 서로 알고 있는
client_id+secret_key기반으로 토큰을 생성하고 검증. - 예: 백오피스 → API 서버, 모바일 푸시 서버 → 인증 서버
- 서로 알고 있는
-
내부 API 인증 (공개되지 않는 내부 시스템 간)
- VPN이나 내부 네트워크에서 실행되는 마이크로서비스 간 통신.
-
3rd Party API 인증 (간단한 API Key + 서명 방식)
- 예: 금융 API (금융결제원, 카드사 등), 물류 API (택배사 등)
timestamp+path+params를 HMAC으로 서명 후 헤더에 포함
-
Webhook 인증
- 외부 시스템에서 전송한 웹훅 요청이 위조되지 않았는지 HMAC 서명으로 검증
⚠️ HMAC 기반 인증 방식의 취약점과 한계
1. 클라이언트 시크릿 유출 시 보안 완전 붕괴
client_secret이 노출되면 누구든지 유효한 토큰을 만들 수 있음- 대응책: secret 주기적 rotation, IP allow list 등 추가 보안 필요.
2. 토큰 재사용 (Replay Attack)
- 유효한 토큰을 탈취해 같은 요청을 반복적으로 보낼 수 있음
- 대응책:
timestamp+nonce사용하거나, Redis로 토큰 1회 사용 제한, 토큰 유효기간을 짧게 설정.
3. HTTPS 미사용 시 중간자 공격
- 네트워크 상에서 HMAC 토큰이 노출될 수 있음
- 대응책: 반드시 HTTPS 사용. 토큰 유효기간을 짧게 설정.
4. 탈중앙 인증이 어려움
- 인증 상태를 외부에서 공유하거나 위임하기 어려움 (JWT보다 불리)
- 대응책: 인증 권한 위임이 필요한 경우에는 OAuth2 또는 JWT 사용 고려
✅ 결론 요약
| 항목 | HMAC 인증 방식의 특징 |
|---|---|
| 장점 | 구현 간단, 의존성 없음, 빠름, 토큰 위조 방지 |
| 단점 | secret 유출 시 위험, 탈취 방지 필요, 위임 인증 어려움 |
| 적합한 경우 | 서버 간 통신, 내부 API, 웹훅 보안 등 제한된 신뢰 환경 |
간단하지만 안전한 인증 구조가 필요할 때 위 HMAC 기반 토큰 방식을 적극 활용해 보세요. 추후 필요 시, IP 제한, 요청 URL 포함, Nonce 추가 등으로 확장도 가능합니다.