Today I Learned
간만에 블로그 글 작성!
로그인 연동 기능을 구현 하다가 각 서명 알고리즘 중 어떤 걸 고를지 고민해보았다.
기존 토큰은 HS256을 사용했는데, 여러 사이트를 하나의 public key로 jwt 키 생성과 검증을 모두 하는 것이 보안적으로 우려되어 다른 방법을 사용해보기 위해 조사해봤다.
JWT 서명 알고리즘 비교: HS256 vs RS256 vs ES256
JWT(JSON Web Token)의 무결성을 보장하기 위해 사용하는 서명 알고리즘은 크게 대칭키 방식과 비대칭키 방식으로 나뉜다.
1. HS256 (HMAC with SHA-256)
대칭키(Symmetric) 암호화 방식 하나의 비밀키(Secret Key)를 사용하여 토큰을 생성(서명)하고 검증
- 특징: 토큰을 만드는 곳과 검증하는 곳이 동일한 키를 공유해야 한다.
- 장점: 속도가 매우 빠르고, 구현이 단순하고, 리소스 소모가 적다.
- 단점: 키가 유출되면 누구나 토큰을 위조할 수 있어 보안 리스크가 크고, 이 때문에 여러 서비스 간에 키를 공유하기가 어렵다.
- 적합한 경우: 단일 서버 내부 통신, 신뢰할 수 있는 소수의 서비스 간 통신.
2. RS256 (RSA Signature with SHA-256)
비대칭키(Asymmetric)암호화 방식으로, 비밀키(Private Key)로 서명하고, 공개키(Public Key)로 검증한다.
- 특징: 인증 서버만 비밀키를 갖고, 검증하려는 클라이언트/서비스는 공개키만 가진다.
업계 표준으로 대부분의 IDP(Identity Provider)가 사용중.
- 장점: 보안성이 높습니다. 공개키가 노출되어도 토큰 위조가 불가능. MSA 구조나 외부 API 제공 시 키 관리가 용이함
- 단점: 수학적 연산이 복잡하여 HS256보다 속도가 느림. 키의 길이가 길어 환경변수 적용이 번거롭고, 오버헤드가 발생할 수 있음
- 적합한 경우: OAuth2, OpenID Connect(OIDC), 마이크로서비스 아키텍처(MSA).
3. ES256 (ECDSA with P-256 and SHA-256)
타원 곡선(Elliptic Curve)을 이용한 비대칭키 방식
- 특징: RSA와 마찬가지로 비대칭키를 사용하지만, 타원 곡선 수학을 기반으로 함
- 장점: RS256보다 훨씬 짧은 키로 동일한 보안 수준을 제공
- 성능: RS256보다 연산 속도가 빠르고 결과값(서명)의 크기도 작음
- 단점: 구현이 RSA보다 복잡할 수 있으며, 일부 오래된 환경에서 지원하지 않을 수 있음
- 적합한 경우: 높은 보안과 성능이 동시에 필요한 현대적인 모바일 앱 및 고성능 백엔드 시스템.
요약 테이블
| 구분 | HS256 | RS256 | ES256 |
|---|
| 방식 | 대칭키 (Secret) | 비대칭키 (Public/Private) | 비대칭키 (Public/Private) |
| 속도 | 가장 빠름 | 보통 | 빠름 |
| 보안성 | 낮음 (키 공유 필요) | 높음 | 매우 높음 |
| 키 길이 | 짧음 | 매우 길음 (2048bit 이상) | 짧음 (256bit) |
| 권장 용도 | 단일 서비스 내부 | 표준 인증 시스템 (OIDC) | 최신 고성능 시스템 |
결론: 무엇을 선택해야 할까?
- 단순하고 빠른 성능이 최우선이며, 서버가 하나라면? HS256
- 보안이 중요하고, 여러 서비스에서 토큰을 검증해야 하는 표준적인 방식을 원한다면? RS256
- 보안과 성능을 모두 잡고 싶고, 최신 사양을 적용하고 싶다면? ES256
ES256 키 생성 방법
openssl ecparam -name prime256v1 -genkey -noout -out private.pem
openssl ec -in private.pem -pubout -out public.pem