didrod205/jwtlens
GitHub: didrod205/jwtlens
jwtlens 是一个完全离线的 JWT 解码、安全审计与本地签名验证工具,解决开发者将敏感 token 粘贴到在线工具所带来的泄露风险。
Stars: 1 | Forks: 0
# 🔍 jwtlens
### 解码、审计并验证 JWT —— 完全离线。停止将有效的 token 粘贴到 jwt.io。
[](https://www.npmjs.com/package/jwtlens)
[](https://github.com/didrod205/jwtlens/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/jwtlens)
[](./LICENSE)
**[🌐 试用浏览器 playground →](https://didrod205.github.io/jwtlens/)** · 粘贴一个 JWT,查看其解码、审计和验证的结果。不会上传任何内容——所有操作均在客户端执行。
API 拒绝了你的请求,于是你从日志中提取出 JWT,并——为了读取它的
claims——将其粘贴到 **jwt.io**。该 token 是一个**生产环境凭证**,而你
刚刚把它发送给了第三方网站。然后你手动查看了 `exp`/`aud`/`alg`,而
要实际检查签名,你还需要在某处*加载*密钥。
**jwtlens 完全在你的机器上解码、安全审计并*验证* JWT。** 无需网站,无需
API 密钥,无需网络。解码 + lint 是纯函数;签名验证通过 `node:crypto`
在本地运行,使用**你自己的 secret、PEM 或 JWK**。
```
echo "$TOKEN" | npx jwtlens scan --key public.pem
```
```
Header
alg "RS256" typ "JWT" kid "k1"
Payload
iss "https://auth.example.com"
sub "user-4012"
exp 1893456900 (in 15m)
iat 1893456000 (in 0s)
Status active
Signature ✓ verified (RS256) — signature matches the supplied key
Score 100/100 (A)
```
## 为什么选择 jwtlens?
- 🔒 **设计上完全离线。** 你的 token(以及签名密钥)永远不会离开你的
机器——这正是不要在生产凭证上使用 jwt.io 的全部理由。
- ✅ **它不仅解码,还会验证。** 针对真实环境的 `node:crypto` 签名检查支持
**HS256/384/512, RS*, PS*, ES256/384/512 和 EdDSA** —— 包括会让简单
的验证器出错的 ECDSA raw (P1363) 签名格式。
- 🛡️ **它会审计安全状况。** `alg: none`、带有已签名 header 但无签名的
情况、缺失/过长的 `exp`、未来的 `iat` 日期、缺失 `aud`/`iss`/`sub`/
`jti`,以及 HS↔RS **alg-confusion** 陷阱——每一项都会附带修复建议。
- 🤖 **确定性强且对 CI 友好。** 相同的 token → 相同的结果。在 CI 中为你的
issuer 设置门控:如果它发出过 `alg: none` 或永久有效的 token,则让构建失败。
为什么不问问 LLM?base64url、claim 的时间和**签名数学**都是精确的——
聊天机器人无法(也不应该)持有你的 secret 来验证签名,而且你需要对 CI 中的
每一个 token 都执行此操作,而不是仅仅一次。
## 安装
```
# 立即运行
echo "$TOKEN" | npx jwtlens scan
# 或添加它
npm install -g jwtlens # global CLI
npm install -D jwtlens # CI / library
```
Node ≥ 18。解码 + lint 无需额外依赖且对浏览器安全;验证使用
`node:crypto`。
## 快速开始
```
jwtlens scan "$TOKEN" # decode + security lint
echo "$TOKEN" | jwtlens scan # from stdin (Bearer prefix ok)
jwtlens scan token.txt --key public.pem # + verify RS/ES/EdDSA
jwtlens scan "$TOKEN" --secret "$HS_SECRET" # + verify HS*
jwtlens verify token.txt --jwk jwks.json # just verify (exit 0/1)
jwtlens scan "$TOKEN" --now 2030-01-01 # evaluate timing at a fixed date
jwtlens scan "$TOKEN" --min-score 80 --md report.md # CI gate + report
```
参见 [`examples/sample-report.md`](./examples/sample-report.md) 以及附带的
`examples/*.jwt.txt`(一个强 RS256 token、一个弱 HS256 token 和一个 `alg: none` token)。
## 检查内容
| 组别 | 示例 |
| ----- | -------- |
| **签名与算法** | `alg: none` (错误),带有空签名的已签名 header,未知的 alg,对称 alg (alg-confusion) 警告 |
| **过期与时间** | 缺失 `exp` (永不过期),生命周期过长,未来的 `iat` |
| **Claims** | 缺失 `aud` / `iss` / `sub` / `jti` |
| **Token 状态** | 已过期,尚未生效 (`nbf`),带有可读的 "3h ago" / "in 15m" |
| **验证** | 使用 `--secret` / `--key` (PEM) / `--jwk` (JWK 或 JWKS,通过 `kid`) 进行本地签名检查 |
检查结果会汇总为 0–100 的分数以及 A–F 的评级,你可以在 CI 中将其用作门控。
## 实际场景
**1. 安全地检查生产 token。** 从日志中提取它,通过管道传入,读取它的
claims 和时间——而无需将凭证交给网站。
```
kubectl logs api | grep -o 'eyJ[^ ]*' | head -1 | jwtlens scan
```
**2. 在本地验证 token 的签名。** 使用公共 JWKS 离线确认 token 确实
来自你的 issuer:
```
jwtlens verify "$TOKEN" --jwk jwks.json && echo "authentic"
```
**3. 在 CI 中为你的 issuer 设置门控。** 断言你的身份验证服务生成的 token 是
格式良好的(已签名、生命周期短、已限定范围):
```
your-cli mint-test-token | npx jwtlens scan --min-score 85
```
## 配置
`jwtlens init` 会生成 `jwtlens.config.json`:
```
{
"ignore": [], // rule ids to skip, e.g. ["no-jti"]
"maxLifetimeSeconds": 86400, // warn above this token lifetime
"clockSkewSeconds": 60, // tolerance for iat/nbf "in the future"
"minScore": 0 // CI gate threshold
}
```
## 库 API
```
import { analyzeToken, verifyJwt, decodeJwt, DEFAULT_CONFIG } from "jwtlens";
const now = Math.floor(Date.now() / 1000);
const { decoded, findings } = analyzeToken(token, DEFAULT_CONFIG, now);
const result = verifyJwt(decoded, { secret: process.env.HS_SECRET });
console.log(result.valid, findings.map((f) => f.rule));
```
`decodeJwt` 和 `lintJwt` 是纯函数(对浏览器安全);`verifyJwt` 使用 `node:crypto`。
## 路线图
- 🤖 **可选的 `--ai` 层(自带 API key)** 用于结合上下文解释 token 的 claims。
核心功能保持 100% 离线且具有确定性。
- 从 `iss`/`.well-known` URL 获取 JWKS(需明确开启;默认关闭)。
- `x5c`/`x5t` 证书链感知以及密钥类型/alg 不匹配检查。
- 加密的 JWE 结构检查(仅限 header)。
- ✅ **一个浏览器 playground**,完全在客户端运行解码 + lint + 验证——
[在这里体验](https://didrod205.github.io/jwtlens/)(不上传任何内容)。
## 💖 赞助
jwtlens 是免费且基于 MIT 协议的,利用业余时间构建和维护。如果它成功帮助你
避免了将有效的 token 发送给第三方网站,请考虑支持它:
- ⭐ **为本仓库点 Star** —— 帮助他人发现它的最简单的免费方式。
- 🍋 **[通过 Lemon Squeezy 赞助](https://elab-studio.lemonsqueezy.com/checkout/buy/5d059b89-51d0-456b-b33a-ed56994f7010)** —— 一次性或周期性赞助。
## 许可证
[MIT](./LICENSE) © jwtlens 贡献者标签:GNU通用公共许可证, JWT, MITM代理, Node.js, SOC Prime, 开发工具, 暗色界面, 服务器监控, 离线验证, 自动化攻击