密钥配置错误、算法未校验、密钥长度不足、硬编码密钥、多密钥轮换失效及TokenLookup路径大小写错误,均会导致JWT认证完全失效。

密钥配置错一个字,整个认证链就形同虚设——不是“可能被绕过”,而是“必然被伪造”。
SigningKey 必须是 []byte,不能是 string
很多人直接传 "my-secret" 给 SigningKey,看似能跑通,但底层会隐式转成 []byte("my-secret")。问题在于:一旦你后续想升级为 RSA 密钥(*rsa.PrivateKey),或做密钥轮换(多个 []byte 切换),类型不一致就会 panic。
- 始终显式声明类型:
SigningKey: []byte(os.Getenv("JWT_SECRET")) - 环境变量注入时确保非空:
if len(jwtSecret) == 0 { log.Fatal("JWT_SECRET is empty") } - 不要用
string(secret)或interface{}("secret")混淆类型边界
SigningMethod 不写死就等于开后门
默认 SigningMethod 是 "HS256",但 echo-jwt 的 KeyFunc 不校验算法——攻击者把 header 改成 {"alg":"none"} 就能绕过签名验证。
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
- 在
KeyFunc里强制检查:if token.Method.Alg() != "HS256" { return nil, errors.New("invalid algorithm") } - 别依赖配置项
SigningMethod做校验,它只影响签发,不影响验证逻辑 - 如果要用 RS256,
SigningKey必须是*rsa.PublicKey,且KeyFunc要返回对应公钥,不能复用 HS256 的密钥类型
密钥长度必须达标,否则 openssl 都救不了你
HS256 要求密钥熵值足够高。用 "secret" 或 123456 这类字符串,c-jwt-cracker 几秒就能爆破出来。
- 生成安全密钥:
openssl rand -base64 32(输出 32 字节 Base64,解码后正好 24 字节) - HS256 推荐最小密钥长度:32 字节原始字节(即 Base64 编码后约 44 字符)
- 硬编码密钥进代码 = 直接给攻击者送钥匙;必须走
os.Getenv()或 Vault
多密钥轮换时 KeyFunc 不能只返回一个密钥
上线新密钥后,旧 token 还没过期,必须同时支持新旧两套密钥验证,否则大量用户会突然 401。
-
KeyFunc应该根据 token header 或 claims 中的kid字段选密钥:if kid == "v2" { return keyV2, nil } - 没有
kid时 fallback 到默认密钥,但要记录日志告警 - 绝不能在
KeyFunc里做网络请求(如查 DB)——超时或失败会导致整个请求 hang 住
最常被忽略的一点:密钥本身没问题,但 TokenLookup 配错了路径,比如把 "header:Authorization" 写成 "header:authorization"(小写),某些代理会丢掉小写 header——连解析都失败,更别说校验了。

















