2020년 10월, JWT(JSON Web Token)에 대한 보안 테스트를 조금 더 편하게 하고자 jwt-hack이라는 도구를 처음 만들었습니다. 당시 Go로 개발했던 이 도구는 crack 기능을 통해 wordlist나 bruteforce 방식으로 JWT 서명의 비밀키(secret)를 찾는 데 핵심을 둔, 저의 필요에 의해 태어난 프로젝트였죠.
그 후로 5년 가까운 시간 동안 다른 프로젝트들에 비해 상대적으로 소홀했던 것이 사실입니다. 조금씩 개선을 이어오긴 했지만, 마음 한편에는 항상 아쉬움이 남아있었습니다. 그래서 이번에 큰마음을 먹고 프로젝트를 완전히 새롭게 재시작하기로 결정했고, 드디어 메이저 버전을 올린 jwt-hack v2를 릴리즈하게 되었습니다.
이번 글에서는 jwt-hack v2의 핵심적인 변화는 무엇인지, 그리고 앞으로 어떤 방향으로 나아갈지에 대한 이야기를 간략하게 공유해볼까 합니다.
From Go to Rust: The Core Change
v2에서 가장 큰 변화는 도구를 작성한 언어가 Go에서 Rust로 완전히 전환되었다는 점입니다. 기존 Go로 작성된 코드를 모두 Rust로 재작성하는 것은 어느 정도 노력이 들어갔지만 그만한 가치가 있는 작업이었다고 생각합니다.
가장 큰 이유는 안정성입니다. 솔직히 v1은 가끔 예측하지 못한 메모리 관련 이슈가 발생하곤 했습니다. Rust의 Ownership 시스템과 컴파일 타임의 엄격한 검사 덕분에 이런 종류의 버그를 예방할 수 있었고, 결과적으로 훨씬 안정적인 처리 능력을 갖추게 되었습니다.
물론 성능 향상은 덤으로 따라왔죠. 간단한 벤치마크 결과만 봐도 꽤 만족스러운 속도 개선이 있었습니다.
Metric | jwt-hack v1 | jwt-hack v2 |
---|---|---|
Time (mean ± σ) | 1.874 s ± 0.033 s | 678.6 ms ± 165.8 ms |
Range (min … max) | 1.834 s … 1.935 s | 623.5 ms … 1150.4 ms |
User Time | 7.312 s | 3516.7 ms |
System Time | 1.985 s | 491.1 ms |
Runs | 10 | 10 |
동일한 조건에서의 crack 기능 성능 비교 ($ jwt-hack crack eyJ0e... --mode brute --max 4
)
Strengthening the Foundation
단순히 언어만 바꾼 것이 아니라, 프로젝트의 내실을 다지는 데에도 신경을 썼습니다.
Test Coverage
v2를 개발하면서 가장 신경 쓴 부분 중 하나가 바로 테스트 코드입니다. 이전 버전에 비해 훨씬 촘촘하게 테스트 코드를 작성하여 코드 변경으로 인한 부작용을 최소화하고, 앞으로 새로운 기능을 추가할 때도 안정성을 유지할 수 있는 기반을 마련했습니다.
Compatibility
메이저 버전이 올라갔지만, 기존 v1에서 사용하시던 Command-line 옵션과 사용법은 모두 그대로 계승하고 있습니다. 따라서 별도의 마이그레이션 작업 없이, 기존에 사용하시던 스크립트나 파이프라인에 그대로 적용하실 수 있습니다.
Expanded Features
Rust로 전환하면서 얻은 안정성과 개발 편의성을 바탕으로, 이전부터 필요하다고 생각했던 여러 기능을 추가했습니다.
Support for More Algorithms
기존에는 HMAC 계열(HS256, HS384, HS512) 위주로 지원했지만, 이제는 비대칭키 암호화 방식인 RSA (RS*)와 ECDSA (ES*) 계열의 알고리즘을 지원합니다.
New Key-Based Functionality
단순히 Secret 기반의 테스트를 넘어, 이제 개인키/공개키(private/public key)를 이용한 토큰 생성, 검증, 테스트가 가능해졌습니다. 예를 들어, 아래와 같이 개인키로 서명된 JWT를 손쉽게 만들 수 있죠.
ssh-keygen -t rsa -b 4096 -E SHA256 -m PEM -P "" -f RS256.key
jwt-hack encode '{"a":"z"}' --private-key RS256.key --algorithm=RS256
New Verify Mode
사실 이전 버전에는 JWT의 서명이 유효한지 검증하는 기본적인 기능조차 없었습니다. 이번 업데이트를 통해 토큰의 서명을 Secret이나 공개키로 검증할 수 있는 verify 모드가 추가되어, 토큰 테스팅 도구로서의 완전성을 높였습니다.
Broader Attack Vector Support
jwt-hack의 핵심 기능 중 하나는 알려진 취약점을 이용한 공격용 토큰을 생성하는 것입니다. 기존 none algorithm, jku/x5u 공격 외에도, 이제 더 다양한 공격 벡터를 지원하며 앞으로도 계속 확장해나갈 예정입니다.
- Algorithm Confusion (alg 헤더를 HS256으로 변조)
- SQL Injection in kid (kid 헤더에 SQLi 페이로드 삽입)
- 기타 알려진 공격 기법들
Installation
Cargo
Rust 개발자라면 누구나 아는 cargo를 통해 바로 설치할 수 있습니다.
cargo install jwt-hack
Homebrew
가장 기쁜 소식 중 하나인데요, 이제 jwt-hack이 공식 homebrew-core에 포함되었습니다! 별도의 tap 등록 없이 아래의 간단한 명령어로 설치하고 업데이트할 수 있습니다.
brew install jwt-hack
More
이외에도 Snapcraft Package, Docker Hub, GHCR 등 다양한 채널을 통해서도 jwt-hack을 사용하실 수 있습니다.
Final Thoughts
오랫동안 방치해두었던 프로젝트에 새 숨을 불어넣는 작업은 생각보다 즐거웠습니다. 도구가 개선되는 모습도 좋았지만, 특히 Rust라는 언어를 더 깊이 알아가는 과정이라 더욱 재미있었습니다. 앞으로 jwt-hack을 JWT 보안 테스팅을 위한 여러 기능을 담은 도구로 만들어 나가려고 합니다. 필요한 기능이나 개선 아이디어가 있다면 주저 마시고 GitHub 이슈에 편하게 의견 남겨주세요! 여러분의 관심이 곧 프로젝트의 원동력이 됩니다.