jwtx-go
A lightweight, secure JWT library for Go — EdDSA & ES256 only.
English · 中文
jwtx-go
jwtx-go is a lightweight JWT library for Go that prioritizes security, simplicity, and zero external runtime dependencies.
Why jwtx-go?
Most JWT libraries support a dozen algorithms — many of which introduce unnecessary attack surface. jwtx-go takes a different philosophy:
Only Two Asymmetric Algorithms
| Algorithm |
Curve |
Go Standard Library |
Security Rationale |
| EdDSA |
Ed25519 |
crypto/ed25519 |
Modern, constant-time, fast, side-channel resistant |
| ES256 |
P-256 |
crypto/ecdsa |
Widely standardized, FIPS-compliant curve |
- No symmetric (HS) algorithms* — eliminates algorithm confusion attacks (CVE-2015-9235, CVE-2016-5431)
- No RSA — avoids large key sizes, slow signing, and padding oracle risks
- No exotic curves — only battle-tested, standard library backed curves
- 100% Go standard library — zero external runtime dependencies
Key ID (Kid) — Built-in Algorithm Routing
jwtx-go uses a numeric Kid in the range 1100–2999 to encode both algorithm selection and capabilities:
Kid Range Algorithm
1100–1999 → EdDSA (Ed25519)
2100–2999 → ES256 (ECDSA P-256)
- The last digit controls additional behavior:
Kid % 10 == 1 — allows CanRefresh in SubConfig, enables ChangeIssuer()
Kid % 10 == 0 — rejected as invalid
- This built-in routing prevents algorithm mix-ups and key confusion at the application level
Custom validation — You can implement your own Kid validation by replacing the Kid field before calling GenJwt() or ParseJwt(), or by extending the library to add your own range checks and business logic on top of the built-in enforcement.
Zero External Runtime Dependencies
go.mod: require github.com/stretchr/testify v1.11.1 // test only
Only testify is needed for testing — your production builds carry zero third-party dependencies.
Features
- ✅ JWT generation and parsing with EdDSA (Ed25519) and ES256 (ECDSA P-256)
- ✅ PEM key parsing for both Ed25519 and ECDSA keys
- ✅ Built-in Key ID (Kid) routing and validation
- ✅
ChangeIssuer() with safe copy semantics
- ✅ Fast path JWT string pre-check (
CheckJwtStr)
- ✅ Auto-expiry with TTL support
- ✅ Configurable
SubConfig payload (AttendeeId, CanRefresh, OpenId)
- ✅ No external dependencies in production
- ✅ High test coverage (98.9%)
Installation
go get github.com/fabletang/jwtx-go
Requires Go 1.21 or later.
Quick Start
package main
import (
"crypto/ed25519"
"time"
"github.com/fabletang/jwtx-go"
)
func main() {
// Generate Ed25519 key
pub, pri, _ := ed25519.GenerateKey(nil)
// Create a token
m := &jwtx.JwtX{
Kid: 1101, // EdDSA
Id: 12345,
PriKey: pri,
PubKey: pub,
Exp: time.Now().Add(5 * time.Minute),
Sub: jwtx.SubConfig{OpenId: "user_abc", CanRefresh: true},
Issuer: 1,
}
token, err := m.GenJwt()
if err != nil { panic(err) }
// Parse & verify
result, err := m.ParseJwt(token)
if err != nil { panic(err) }
println(result.Sub.OpenId) // "user_abc"
}
API Overview
Core Types
| Type |
Description |
JwtX |
Main JWT struct with all parameters |
SubConfig |
Custom payload (AttendeeId, OpenId, CanRefresh) |
JwtHeader |
JWT header (Alg, Kid, Typ) |
EcdsaKey |
Parsed ECDSA key pair |
Ed25519Key |
Parsed Ed25519 key pair |
Key Functions
| Function |
Description |
GenJwt() |
Generate a signed JWT string |
ParseJwt() |
Parse and verify a JWT string |
ChangeIssuer() |
Create a new token with a different issuer |
CheckJwtStr() |
Fast pre-check on JWT format (no crypto) |
GetEd25519Key() |
Parse Ed25519 PEM keys |
GetEcdsaKey() |
Parse ECDSA PEM keys (PKCS1 or PKCS8) |
Benchmark Results
goos: darwin
goarch: arm64
cpu: Apple M1 Pro
BenchmarkGenJwt_Ed25519-10 23.5 µs/op 2738 B/op 37 allocs/op
BenchmarkGenJwt_ECDSA-10 26.3 µs/op 8961 B/op 98 allocs/op
BenchmarkParseJwt_Ed25519-10 48.8 µs/op 3232 B/op 61 allocs/op
BenchmarkParseJwt_ECDSA-10 62.2 µs/op 4448 B/op 82 allocs/op
BenchmarkCheckJwtStr-10 0.65 µs/op 368 B/op 9 allocs/op
BenchmarkParseWithClaims_Ed25519-10 47.0 µs/op 2248 B/op 41 allocs/op
BenchmarkSign_Ed25519-10 19.9 µs/op 168 B/op 5 allocs/op
BenchmarkVerify_Ed25519-10 43.4 µs/op 0 B/op 0 allocs/op
Run benchmarks on your own hardware:
go test -bench=. -benchmem -count=5 ./...
License
Apache 2.0. See LICENSE.
jwtx-go
jwtx-go 是一个轻量级 Go JWT 库,专注于安全性、简洁性,且生产环境零外部依赖。
为什么选择 jwtx-go?
大多数 JWT 库支持十几种算法,其中许多引入了不必要的攻击面。jwtx-go 采用不同的理念:
仅两种非对称算法
| 算法 |
曲线 |
Go 标准库 |
安全理由 |
| EdDSA |
Ed25519 |
crypto/ed25519 |
现代、常量时间、快速、抗侧信道攻击 |
| ES256 |
P-256 |
crypto/ecdsa |
广泛标准化、FIPS 兼容曲线 |
- 不实现对称 (HS*) 算法 — 彻底消除算法混淆攻击(CVE-2015-9235、CVE-2016-5431)
- 不实现 RSA — 避免大密钥、慢签名和填充预言攻击风险
- 不实现另类曲线 — 仅采用经过实战检验的标准库曲线
- 100% Go 标准库 — 生产环境零外部依赖
Key ID (Kid) — 内置算法路由
jwtx-go 使用 1100–2999 范围的数值型 Kid,同时编码算法选择和功能特性:
Kid 范围 算法
1100–1999 → EdDSA (Ed25519)
2100–2999 → ES256 (ECDSA P-256)
- 个位数控制额外行为:
Kid % 10 == 1 — 允许 SubConfig 中的 CanRefresh,启用 ChangeIssuer()
Kid % 10 == 0 — 拒绝,视为无效
- 内置路由避免了应用层的算法误配和密钥混淆
自定义验证 — 您可以通过在调用 GenJwt() 或 ParseJwt() 之前自行设置 Kid 字段来实现自定义校验逻辑,或在内置规则之上添加自己的范围检查与业务逻辑。
零外部运行时依赖
go.mod: require github.com/stretchr/testify v1.11.1 // 仅测试使用
仅 testify 用于测试,生产构建零第三方依赖。
功能特性
- ✅ JWT 签发与解析,支持 EdDSA (Ed25519) 和 ES256 (ECDSA P-256)
- ✅ PEM 密钥解析,支持 Ed25519 和 ECDSA
- ✅ 内置 Key ID (Kid) 路由与校验
- ✅
ChangeIssuer() 安全复制语义
- ✅ JWT 字符串快速预检(
CheckJwtStr,不涉及密码运算)
- ✅ 自动过期与 TTL 支持
- ✅ 可配置
SubConfig 载荷(AttendeeId、CanRefresh、OpenId)
- ✅ 生产环境无外部依赖
- ✅ 高测试覆盖率(98.9%)
安装
go get github.com/fabletang/jwtx-go
需要 Go 1.21 或更高版本。
快速开始
package main
import (
"crypto/ed25519"
"time"
"github.com/fabletang/jwtx-go"
)
func main() {
// 生成 Ed25519 密钥
pub, pri, _ := ed25519.GenerateKey(nil)
// 创建令牌
m := &jwtx.JwtX{
Kid: 1101, // EdDSA
Id: 12345,
PriKey: pri,
PubKey: pub,
Exp: time.Now().Add(5 * time.Minute),
Sub: jwtx.SubConfig{OpenId: "user_abc", CanRefresh: true},
Issuer: 1,
}
token, err := m.GenJwt()
if err != nil { panic(err) }
// 解析与验证
result, err := m.ParseJwt(token)
if err != nil { panic(err) }
println(result.Sub.OpenId) // "user_abc"
}
API 概览
核心类型
| 类型 |
说明 |
JwtX |
主 JWT 结构体,包含所有参数 |
SubConfig |
自定义载荷(AttendeeId, OpenId, CanRefresh) |
JwtHeader |
JWT 头部(Alg, Kid, Typ) |
EcdsaKey |
已解析的 ECDSA 密钥对 |
Ed25519Key |
已解析的 Ed25519 密钥对 |
关键函数
| 函数 |
说明 |
GenJwt() |
生成签名后的 JWT 字符串 |
ParseJwt() |
解析并验证 JWT 字符串 |
ChangeIssuer() |
创建具有不同签发者的新令牌 |
CheckJwtStr() |
JWT 格式快速预检(不涉及密码运算) |
GetEd25519Key() |
解析 Ed25519 PEM 密钥 |
GetEcdsaKey() |
解析 ECDSA PEM 密钥(支持 PKCS1 或 PKCS8) |
性能测试结果
goos: darwin
goarch: arm64
cpu: Apple M1 Pro
BenchmarkGenJwt_Ed25519-10 23.5 µs/op 2738 B/op 37 allocs/op
BenchmarkGenJwt_ECDSA-10 26.3 µs/op 8961 B/op 98 allocs/op
BenchmarkParseJwt_Ed25519-10 48.8 µs/op 3232 B/op 61 allocs/op
BenchmarkParseJwt_ECDSA-10 62.2 µs/op 4448 B/op 82 allocs/op
BenchmarkCheckJwtStr-10 0.65 µs/op 368 B/op 9 allocs/op
BenchmarkParseWithClaims_Ed25519-10 47.0 µs/op 2248 B/op 41 allocs/op
BenchmarkSign_Ed25519-10 19.9 µs/op 168 B/op 5 allocs/op
BenchmarkVerify_Ed25519-10 43.4 µs/op 0 B/op 0 allocs/op
在自己的机器上运行性能测试:
go test -bench=. -benchmem -count=5 ./...
开源协议
Apache 2.0。详见 LICENSE。