JWT 工具
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}sub· 主體1234567890name· NameJohn Doeadmin· Admintrueiat· 簽發時間1516239022→ 2018/01/18 09:30:22algHS256HMAC(對稱)typ· TypeJWT免費線上 JWT 工作台:解碼、驗證並生成 JSON Web Token。支援 13 種演算法、PEM/JWK 金鑰、自動生成金鑰對、exp/iat/nbf 自動解析,所有操作都在瀏覽器本地完成。
相關推薦
生成 HMAC-SHA256 密钥用于 JWT HS256 签名
JWT HS256 本质是 HMAC + Base64URL 编码,先学 HMAC 再用 JWT
JWT 内部使用的 Base64URL 编码原理
JWT Header/Payload/Signature 都是 Base64URL 编码
Base64URL 解码 JWT 三段内容
JWT 三段拆解后做 Base64URL 解码查看明文
需要加密 Payload 时改用 JWE / AES
JWT 默认明文可读,敏感 Payload 应改用 JWE / AES
HS256 签名底层的 SHA-256 哈希
HS256 = HMAC + SHA-256,先理解 SHA-256
用生成的 JWT 直接测 API 接口
JWT 调试完后直接拼到 Authorization: Bearer 头测试
正規表達式測試器
什麼是JWT 工具?
JWT(JSON Web Token)是 IETF 在 RFC 7519 中定义的开放标准(RFC 7515 描述其 JWS 簽章形式,RFC 7516 描述 JWE 加密形式,RFC 7517 定义 JWK 金鑰),用于在 HTTP 请求、OIDC 流程、微服务调用之间安全传递「已声明」的使用者信息。一个标准 JWT 字符串由三段 Base64URL 编码组成:Header(演算法与类型)、Payload(Claims,承载使用者数据)、Signature(用金鑰对前两段的簽章)。三段之间用英文点号 `.` 分隔,例如 `eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`。
**JWT ≠ 加密**。这是最常见的误解。Payload 默认是「明文可读」的——任何人都可以用 Base64URL 解碼看到内容。JWT 提供的是「**防篡改**」而不是「**防窃听**」:服务端用金鑰对 Header.Payload 重新簽章并与原 Signature 对比,若一致则证明 Token 在传输中没被改过。这正是火车票「二维码可读 + 防伪钢印」的隐喻:检票员关心的是「票是不是真的」,而不是「二维码看不清」。
JWT 在 13 种演算法之间做了明确分工。**HMAC 类**(HS256/HS384/HS512)用对称金鑰签发和验证,速度快、实现简单,适合单机服务或同一信任域内的服务集群;金鑰长度必须 ≥ 摘要长度(如 HS256 至少 32 字节)。**RSA 类**(RS256/RS384/RS512)用 RSASSA-PKCS1-v1_5,是最常见的非对称方案,签发方持私钥、验证方持公钥。**RSA-PSS 类**(PS256/PS384/PS512)用更新的 RSA-PSS 填充,安全性更高,AWS SigV4 与新晋 OIDC IdP 倾向使用。**ECDSA 类**(ES256/ES384/ES512)用椭圆曲线(分别为 P-256/P-384/P-521),簽章更短、性能更好。**EdDSA**(主要为 Ed25519)簽章速度极快、确定性簽章(同一消息同一金鑰必出同一簽章),是 OAuth 2.1 与新协议的推荐演算法。
安全是 JWT 在生产环境最容易踩雷的地方。OWASP 在 JWT Cheat Sheet 中强调至少 4 条红线:(1) 永远不要在 Payload 里放密码、身份证、银行卡、API Key 等明文敏感信息;(2) 服务端**不要相信** Token Header 中声明的 `alg`,必须用配置写死的演算法校验,否则攻击者改 `alg: none` 就能绕过(这是历史上 CVE-2015-9235 等漏洞的根因);(3) HMAC 金鑰不能用短字符串,至少 32 字节随机数;(4) 验证不能只看簽章,还要校验 `exp`(过期时间)、`nbf`(生效时间)、`iss`(签发者)、`aud`(受众)。本工具在 UI 上把这些 Claims 全部高亮展示,就是为了让排障时一眼看出问题到底在「簽章」「时间」还是「Claims」。
JWT 与 Session 不是替代关系。Session 把使用者状态存到服务端(Redis / 数据库),JWT 把状态装进 Token 里。微服务架构、无状态 API、移动端、CORS 跨域场景下 JWT 更省事;但传统企业系统、要求实时撤销(如「踢人下线」)的场景仍更适合 Session。本工具同时适合「纯 JWT 调试」与「Session 转 JWT 迁移」中的 Token 解析、簽章验证、Payload 编辑场景。
適用場景
- 在线解碼 JWT:除錯 OAuth 2.0 / OIDC 登录时快速拆解 Token,查看 Header 演算法与 Payload Claims 实际值
- 驗證 JWT 签名:用 Secret / 公钥实时校验 Token 签名,快速判断 401 Unauthorized 是「签名错」还是「过期」还是「演算法不匹配」
- 联调生成测试 JWT:开发期间用一对测试金鑰在浏览器内直接签发 JWT,避免每次都让后端临时改代码生成
- PEM ↔ JWK 转换:OIDC IdP 给的是 JWK、服务端要 PEM 时直接在线互转;或反过来,节省自己写 OpenSSL 脚本的时间
- 排查 401 Unauthorized:分步确认 Token 是否过期、alg 是否与网关一致、金鑰是否匹配、PEM 格式是否正确
- 对比 RS256 与 PS256:很多 OIDC 服务用 RS256,AWS SigV4 体系偏好 PS256,本工具可一键切换演算法并复用同一对 RSA 金鑰对比结果
- 学习 JWT 原理:在浏览器里改 alg / 改 Payload / 改金鑰,直观看到「为什么改一个字节签名就失效」,比看 RFC 文字快得多
使用方法
- 粘贴或输入 Token:把待调试的 JWT 字符串贴到输入框,工具自动拆解 Header、Payload、Signature 三段并 JSON 格式化展示
- 選擇演算法:在 HS256 / RS256 / ES256 / PS256 / EdDSA 之间切换,工具按 Header.alg 自动推断并提示不匹配
- 导入金鑰:粘贴 HMAC Secret、或 PEM 字符串、或 JWK JSON;非对称演算法可点击「生成金鑰对」直接得到测试用金鑰
- 驗證或重新签名:Decode 模式用公钥验签并显示「✅ 签名通过 / ❌ 签名失败」;Encode 模式修改 Claims 后用私钥生成新 Token
Output Example
A real MP3 file encoded to a Data URI — copy-ready:
Header (Base64URL): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload(Base64URL): eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE2MjM5MDIyfQ
Signature: kZJfaYjK3iCkVFL5EL9zGRZ5SmD8_x2h6B5c7pVFfVGo
Header 解码:
{
"alg": "HS256",
"typ": "JWT"
}
Payload 解码:
{
"sub": "1234567890",
"name": "Jane Doe",
"iat": 1716239022 // 2024-05-20 14:23:42 UTC
}功能特點
- 解碼 + 驗證 + 生成三合一:粘贴 Token 一键拆解 Header/Payload/Signature;切换演算法与金鑰即可驗證簽章;改完 Claims 重新簽章即可生成新 Token,覆盖完整 JWT 排障链路
- 13 种演算法全支持:HS256/HS384/HS512(HMAC)、RS256/RS384/RS512(RSA-PKCS1-v1_5)、ES256/ES384/ES512(ECDSA)、PS256/PS384/PS512(RSA-PSS)、EdDSA,覆盖 OAuth 2.0、OIDC、JWS、API 网关、企业 SSO 全部主流场景
- PEM / JWK 双格式:RSA、ECDSA、Ed25519 金鑰同时支持 PEM 字符串(带 -----BEGIN PUBLIC KEY----- 头)与 JWK JSON(kid/kty/n/e 等字段),直接对接 OIDC Discovery /.well-known/jwks.json 输出
- HMAC Secret 多种输入形式:支持原始字符串、Hex 字节、Base64 / Base64URL 编码的金鑰,一键切换,避免「看起来一样但验签失败」
- 金鑰对自动生成:RSA-2048、RSA-4096、P-256、P-384、Ed25519 随机生成金鑰对并展示 PEM / JWK 双格式,方便联调时立即获得一对测试金鑰
- Claims 语义增强:exp / iat / nbf 自动转可读时间,过期 / 未生效 / 已签发状态高亮,Header 中 alg / typ / kid 等关键字段单独标注
- 瀏覽器本地零上傳:所有解析、验签、簽章均通过瀏覽器原生 Web Crypto API 完成,Token、金鑰、Payload 永远不出瀏覽器,符合「不把生产 Token 贴到陌生在线工具」的安全原则
- 一键复制:Header、Payload、Signature、生成的新 Token 可分别复制,用于文档、Issue、curl 测试命令
程式碼範例
50 行 Node.js:手写 HS256 签发与验签
javascript把 JWT 最核心的机制讲明白:Header + Payload 先 Base64URL 编码,再对 header.payload 做 HMAC-SHA256。生产中应改用 jsonwebtoken / jose 等库,但这一段足够你理解签名验证为什么失败。
const crypto = require('node:crypto')
function b64url(input) {
return Buffer.from(input)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
}
function hmacSign(data, secret) {
return b64url(crypto.createHmac('sha256', secret).update(data).digest())
}
function sign(payload, secret) {
const header = b64url(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
const body = b64url(JSON.stringify(payload))
const signature = hmacSign(`${header}.${body}`, secret)
return `${header}.${body}.${signature}`
}
function verify(token, secret) {
const [h, p, s] = token.split('.')
const expected = hmacSign(`${h}.${p}`, secret)
const a = Buffer.from(s)
const b = Buffer.from(expected)
return a.length === b.length && crypto.timingSafeEqual(a, b)
}
const SECRET = 'my-super-secret-key'
const payload = { userId: 42, role: 'admin', exp: Math.floor(Date.now() / 1000) + 3600 }
const token = sign(payload, SECRET)
console.log(token)
console.log(verify(token, SECRET)) // true
console.log(verify(token, 'wrong-key')) // false浏览器端:用 Web Crypto API 做 HMAC 签名
html本工具前端的核心思路:浏览器原生 crypto.subtle 直接完成 HMAC / RSA / ECDSA / RSA-PSS / Ed25519 验签,无需任何第三方库。复制这段到任意 HTML 页面即可签发 HS256。
<!doctype html>
<html>
<body>
<pre id="out"></pre>
<script>
const out = document.getElementById('out')
const b64url = buf =>
btoa(String.fromCharCode(...new Uint8Array(buf)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
const b64urlStr = str => b64url(new TextEncoder().encode(str))
async function sign(payload, secret) {
const header = b64urlStr(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
const body = b64urlStr(JSON.stringify(payload))
const data = new TextEncoder().encode(`${header}.${body}`)
const key = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
)
const sig = await crypto.subtle.sign('HMAC', key, data)
return `${header}.${body}.${b64url(sig)}`
}
;(async () => {
const token = await sign({ user: 'alice', role: 'admin' }, 'browser-demo-secret')
out.textContent = token
})()
</script>
</body>
</html>Node.js:用 jose 验证 RS256(标准做法)
javascript生产代码中请用 jose / jsonwebtoken / pyjwt 等成熟库,不要自己写。这段展示如何用 jose 验证一个 RS256 签名的 JWT,验证失败时打印失败原因(alg 不匹配、签名错、过期、kid 找不到等)。
import { jwtVerify, importSPKI } from 'jose'
import { readFile } from 'node:fs/promises'
const token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.payload.signature'
const publicKeyPem = await readFile('public.pem', 'utf8')
try {
const { payload, protectedHeader } = await jwtVerify(
token,
await importSPKI(publicKeyPem, 'RS256'),
{
issuer: 'https://idp.example.com',
audience: 'my-app',
algorithms: ['RS256'], // 关键:白名单算法,禁掉 alg: none / HS256 替换攻击
}
)
console.log('alg =', protectedHeader.alg)
console.log('sub =', payload.sub)
} catch (err) {
console.error('verify failed:', err.code, err.message)
// 常见:ERR_JWT_EXPIRED / ERR_JWS_INVALID / ERR_JWS_SIGNATURE_VERIFICATION_FAILED
}Python:用 PyJWT 解析 Token 并打印 Claims
pythonPython 端调试 JWT 的最常用方式。PyJWT 的 decode() 默认会校验 exp / nbf / iat,并把结果直接转成 dict。
import jwt
token = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxw'
# 解析(不验签,仅看 Payload / Header)
print(jwt.get_unverified_header(token))
# {'alg': 'HS256', 'typ': 'JWT'}
print(jwt.decode(token, options={'verify_signature': False}))
# {'sub': '1234'}
# 完整验签
claims = jwt.decode(
token,
'my-super-secret-key',
algorithms=['HS256'],
audience='my-app',
issuer='my-service',
)
print(claims['sub'])5 類 JWT 簽章演算法對比:該選哪個?
JWT 並非單一演算法,5 類演算法在金鑰、效能、安全性、相容性上各有取捨。先看場景再選演算法,能少走很多彎路。
| 演算法 | 類型 | 金鑰 | 效能 | 典型場景 | 注意點 |
|---|---|---|---|---|---|
HS256 | HMAC 對稱 | 同一 Secret | 極快 | 服務叢集內部、可信賴環境、單體應用 | Secret 不能洩漏給驗證方;至少 32 位元組隨機 |
RS256 | RSA 非對稱 | 私鑰簽 / 公鑰驗 | 中 | OIDC、API 閘道、企業 SSO、公私鑰需要分離 | 用 RSASSA-PKCS1-v1_5,跨語言需固定 padding |
PS256 | RSA-PSS 非對稱 | 私鑰簽 / 公鑰驗 | 中 | AWS SigV4、AWS Cognito、新晉 OIDC IdP | 必須明確固定 saltLength(OpenSSL/jose=32,Go=hash 長度) |
ES256 | ECDSA 非對稱 | 私鑰簽 / 公鑰驗 | 快 + 簽章短 | Apple Sign in with Apple、行動端、低頻寬場景 | 不同曲線(P-256/P-384/P-521)必須與服務端一致 |
EdDSA | Ed25519/Ed448 | 私鑰簽 / 公鑰驗 | 極快(確定性簽章) | OAuth 2.1、新協定、高頻驗簽 | Web Crypto 支援 Ed25519,Ed448 暫未全平台啟用 |
最佳实践
生產環境的 Secret / 私鑰永遠不貼到任何線上工具
本工具雖然 100% 在瀏覽器本地處理(不上傳任何 Token 與金鑰),但除錯流程一旦形成習慣,極易在後續把生產環境的長期 Secret / 私鑰 / Access Token 誤貼到陌生線上工具或截圖洩漏。長期 Token(Refresh Token、生產私鑰、API Key)必須在本地受控環境處理;本工具只用於除錯短期 Access Token、聯調測試金鑰對、學習 JWT 結構。
OWASP JSON Web Token Cheat Sheet服務端必須白名單演算法,絕不信任 Token Header.alg
alg: none 攻擊(CVE-2015-9235 等)和 HS256 替換攻擊(用公鑰當 Secret 騙 RSA 服務端)都源於服務端按 Header 聲明的演算法選驗簽邏輯。生產程式碼必須寫死白名單 algorithms,例如 `algorithms: ['RS256']`,禁止讓 Token 自己決定用哪個演算法。除錯時若發現 Header.alg 與服務端預期不一致,優先懷疑服務端設定而不是 Token 內容。
HS256 Secret 至少 32 位元組隨機數
HS256 用 HMAC-SHA256,金鑰長度若低於摘要長度(32 位元組)會顯著降低暴力列舉成本。不要用 `'my-secret'`、`'password123'` 這類短字串,也不要用業務名/公司名/年份拼接。標準做法:`openssl rand -base64 32` 或 `crypto.randomBytes(32).toString('base64url')` 生成後存到環境變數 / KMS / 金鑰管理服務,絕不寫進程式碼。
JWT 適合存使用者敏感資訊嗎?生產 JWT 必須驗證 exp / nbf / iat / iss / aud,不能只驗簽名
簽名通過只證明「沒被篡改」,但不證明「還沒過期」「確實是這家 IdP 簽的」「確實是給本應用簽的」。生產環境必須強制校驗 exp(過期)、nbf(生效時間)、iat(簽發時間)、iss(簽發者)、aud(受眾)所有相關 Claim,缺一不可。OWASP 明確把這 4-5 項作為必查項。只驗簽名不驗時間是大量 Token 洩漏事件(refresh token 永遠不過期)的根源。
Token 過期時間分層:Access 15-30 分鐘,Refresh 7-30 天
Access Token 負責 API 呼叫,過期時間越短越安全(洩漏後很快失效);Refresh Token 負責換 Access Token,過期時間可以長但必須存服務端、可撤銷。常見經驗值:Access 15-30 分鐘,Refresh 7-30 天,配合 Refresh Token Rotation(每次用 Refresh 換 Access 時同時換新的 Refresh,舊 Refresh 立即失效)能在洩漏偵測與使用者體驗間取平衡。
無狀態 vs 有狀態認證:JWT ≠ Session 的替代品
JWT 把狀態裝進 Token 裡,天然支援微服務橫向擴展和 CORS 跨域,但撤銷成本高(需要黑名單或短過期)。Session 把狀態存到服務端 Redis / DB,能「踢人下線」但需要共用儲存。**不是二選一**:短期 Access JWT + 服務端 Refresh Token 會話記錄是最常見的混合方案,能同時拿到無狀態擴展和即時撤銷。需要即時撤銷的金融/政務核心系統慎用純 JWT。
JWT 適合存使用者敏感資訊嗎?Payload 預設明文可讀,敏感資料不要塞進 JWT
JWT(JWS)預設不加密 Payload,任何拿到 Token 的人用 Base64URL 一解碼就看到內容。**絕對不要**把密碼、身分證字號、銀行卡號、API Key、Access Token、Refresh Token 放進 Payload。JWT 適合放非敏感的 Claims(使用者 ID、角色、過期時間、租戶 ID),敏感資料由服務端按 sub 二次查詢。需要加密 Payload 時改用 JWE(RFC 7516),但效能慢 2-5 倍,且增加金鑰管理複雜度——優先考慮「非敏感 Claim + 服務端查詢」模式。
什麼是 JWT?RSA-PSS(PS256/PS384/PS512)跨語言聯調務必先固定 saltLength
RS256 和 PS256 不能互驗(不同 padding),PS256 還有個易踩的坑:`saltLength` 參數。OpenSSL 預設 32 位元組、Node jose 預設 32 位元組、Python PyJWT 預設等於 hash 長度(SHA-256=32)、Go 預設 `rsa.PSSSaltLengthEqualsHash`。跨語言聯調時務必先固定同一個值(推薦 32 位元組),否則同一對 RSA 金鑰簽出來的 PS256 Token 在不同語言驗簽會失敗。
RS256 和 PS256 跨語言簽章驗證失敗除錯流程:用測試金鑰對,不碰生產
聯調或本地開發時,永遠先生成一對全新的測試金鑰(HS256 用隨機 Secret、RS256/ES256/EdDSA 用工具一鍵生成的金鑰對),絕不複用生產 IdP 的私鑰或公司域名的 Secret。除錯完成或本地測試結束後立即銷毀測試金鑰。本工具的「生成金鑰對」功能正是為此設計,RSA-2048/4096、P-256/P-384、Ed25519 一鍵生成後立即可用,聯調結束直接丟棄。
聯調生成測試 JWT常見問題
JWT 三段结构分别是什么?
JWT 字符串由 `Header.Payload.Signature` 三段组成,每段都是 Base64URL 编码。Header 声明演算法(如 HS256、RS256)和 Token 类型(typ: JWT);Payload 携带使用者声明(Claims),常见字段有 sub(使用者 ID)、iat(签发时间)、exp(过期时间)、nbf(生效时间)、aud(受众)、iss(签发者);Signature 是用金鑰对前两段簽章后的结果,作用是「防篡改」而不是「防偷看」。
解碼 JWT 之后可以修改 Payload 吗?
可以查看和编辑,但**不能伪造**。一旦你改了 Header 或 Payload,原始 Signature 立刻失效,服务端验签会拒绝。要让修改后的 Token 重新可用,必须用相同演算法和金鑰**重新簽章**——这正是本工具提供「解碼 + 编辑 + 生成」三合一的原因:解碼看一眼,改完直接生成新 Token 用于测试,避免每次都让后端临时改代码签发。
HS256、RS256、ES256、PS256、EdDSA 有什么区别?
HS256 是 HMAC + SHA-256,对称金鑰(签发验签用同一 Secret),实现简单速度快。RS256 是 RSASSA-PKCS1-v1_5 + SHA-256,非对称(私钥签 / 公钥验),最常见的 OIDC 演算法。PS256 是 RSA-PSS,RS256 的安全升级版,AWS SigV4 / Cognito 等服务偏好。ES256 是 ECDSA + P-256,簽章短、性能好,Apple Sign in with Apple 默认使用。EdDSA(Ed25519)是下一代演算法,簽章确定且极快,OAuth 2.1 推荐。本工具支持全部 13 种演算法,可在 UI 自由切换。
为什么我的 JWT 一直「Invalid Signature」?
最常见的 5 个原因:(1) 金鑰不匹配——服务端 Secret / 公钥与工具中粘贴的不一致(注意 PEM 头尾、空行、空格);(2) Base64 与 Base64URL 混用——JWT 一定是 Base64URL(`+` → `-`、`/` → `_`、去掉 `=`),用标准 Base64 解碼必然算错簽章;(3) 演算法选错——Header 写 HS256 但服务端按 RS256 验;(4) Secret 被错误地按 Hex / Base64 解碼了一次——本工具的「Secret 输入格式」可显式指定 UTF-8 / Hex / Base64,避免双层解碼;(5) 服务端时钟漂移导致 iat 比当前时间还靠后,被认为是「未生效」Token。
RS256 和 PS256 可以用同一对 RSA 金鑰互相验签吗?
**不能**。RS256 用 RSASSA-PKCS1-v1_5,PS256 用 RSA-PSS,两者簽章长度、填充方式、验签逻辑都不同。同一对 RSA 金鑰签出来的 RS256 Token 用 PS256 验签必然失败,簽章末尾可能还差几个字节。务必让签发方和驗證方用同一种演算法。RSA-PSS 还有 `saltLength` 参数,OpenSSL 默认 32、Node jose 默认 32、Go 默认等于 hash 长度,跨语言联调时务必先固定这个值。
什么是 alg: none 攻击?怎么防?
alg: none 攻击是 JWT 历史上最经典的漏洞(CVE-2015-9235 等)。攻击者把 Token Header 改成 `{"alg": "none"}` 并把 Signature 段清空,如果服务端按 Header 声明的演算法选择「none 演算法」就直接放行。还有一种变种:把 RS256 Token 改成 HS256,把公钥当作 Secret 来签,服务端如果让 Token 决定演算法就会被骗。**防御方法只有一条**:服务端写死白名单 `algorithms: ['RS256']`,绝不让 Token 告诉服务端用哪个演算法。本工具在 UI 上同时显示 Header.alg 与你实际选择的演算法,并在不一致时高亮提示。
PEM 和 JWK 怎么互转?哪个更常用?
PEM 是带 `-----BEGIN PUBLIC KEY-----` 头尾的 Base64 字符串,传统 OpenSSL / Java / Go 体系最常用。JWK 是 JSON 结构(`{kty, n, e, kid, alg}` 等字段),OAuth 2.0 / OIDC 体系标准。OIDC IdP 一般通过 `/.well-known/jwks.json` 端点直接发布公钥 JWK;服务端用 JOSE 库(jose、PyJWT、jsonwebtoken)解析。互转在线就能做——本工具的 RSA / ECDSA / Ed25519 区段直接支持粘贴 PEM 或 JWK,并显示对方格式的等价表示。
JWT 可以在浏览器里直接验签吗?
可以。浏览器原生 Web Crypto API(`window.crypto.subtle`)支持 HMAC、RSA、ECDSA、RSA-PSS、Ed25519 的簽章与验签,无需任何第三方库。本工具就是直接用 `crypto.subtle.importKey` + `crypto.subtle.verify` 在前端完成所有验签,所以完全不上传 Token 与金鑰。但请注意:Web Crypto API 仅在 **HTTPS** 或 `localhost` 域下可用,且不能操作非密码学安全场景的金鑰。
我的 Token 会上传到服务器吗?
不会。本工具所有解析、验签、簽章都通过浏览器原生 Web Crypto API 在前端完成;Token、Header、Payload、Signature、Secret / 私钥、生成的金鑰对都不会发送到任何伺服器。打开浏览器开发者工具的 Network 面板可以看到没有任何出站请求承载 Token 内容。页面加载完成后断网仍可继续使用。
JWT 适合存用户敏感信息吗?
**不适合**。JWT Payload 默认是明文可读——任何拿到 Token 的人都能 Base64URL 解碼看到内容,不存在加密。所以**绝对不要**把密码、身份证号、银行卡号、API Key、Access Token、Refresh Token 等明文敏感信息放进 JWT。需要加密请用 JWE(RFC 7516)而不是 JWS。JWT 适合放非敏感的 Claims(使用者 ID、角色、过期时间、租户 ID),敏感数据由服务端按 sub 二次查询。
故障排查
签名失败:「Invalid Signature / signature is invalid」
Token 与验证密钥不匹配。常见原因:(1) 服务端用的密钥和你粘到工具里的密钥不一致(最常见);(2) 密钥含不可见字符(末尾空格、换行、零宽字符);(3) Base64 与 Base64URL 混用;(4) 算法选错(Header 写 HS256,服务端却按 RS256 验签,或反之)。先核对密钥字节级是否完全一致:注意 PEM 末尾的换行符、HMAC secret 末尾的空格、JWK 的 `k` 值是否被错误地 URL 解码过。再确认工具里选的算法与 Token Header.alg 一致。必要时用本工具的「解码 + 验签」功能直接复现,看错误是否在「解码成功 → 验签失败」这一步。
HTTP 401 Unauthorized:Token Expired / iat in the future
签名校验通过,但 `exp` 已过(Token Expired)、`nbf` 还未到(Not Before)、`iat` 比服务器当前时间还靠后(多见于时钟不同步)。另一种常见情况是 `aud`(audience)不对:Token 是给 App A 签的,被错放到 App B 校验。用本工具的 Claims 高亮区一眼看出 exp / nbf / iat 状态。exp 红色 = 已过期,请重新签发;nbf 红色 = 尚未生效,检查 iat 是否是未来时间;aud 红色 = 受众错,检查服务端是否配置了正确的 audience。
PEM / JWK 格式报错:无法导入密钥
PEM 字符串里多了空行 / 少了头尾标记(`-----BEGIN PUBLIC KEY-----`)、JWK 缺字段(`kty` / `n` / `e` / `kid`)、JWK 里的 `k` 值没去 Base64URL Padding(应为 `=` 补齐或严格去 `=`)、RSA 私钥被错当成公钥导入、Ed25519 私钥(32 字节 seed)误用 64 字节长度。用 `openssl rsa -in key.pem -pubout -outform PEM` 或 `openssl ec -in key.pem -pubout` 重新导出标准 PKIX PEM;JWK 用 OIDC Discovery `/.well-known/jwks.json` 的原始输出,不要自己手动转码。本工具会自动识别 PEM 头、缺失 Padding、JWK 关键字段缺失并给出提示。
RS256 与 PS256 跨语言签名验证失败
RS256 用 RSASSA-PKCS1-v1_5,PS256 用 RSA-PSS。两者**不能互验**——同一对 RSA 密钥签出来的 RS256 Token 用 PS256 验签必然失败,签名长度还可能差几个字节。确认签发方和验证方使用同一种算法。AWS SigV4 用 PS256,多数 OIDC IdP 用 RS256。RSA-PSS 还有 `saltLength` 参数,OpenSSL 默认 32、jose 默认 32、Go 用 `rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}` 才对得上,跨语言联调务必先固定这个值。
alg: none 攻击 / HS256 密钥替换攻击
服务端按 Token Header 中声明的 `alg` 选择验签算法,攻击者把 Header 改成 `alg: none`(无签名)或改成 `HS256`(用对称密钥当公钥来骗 RSA 服务端),绕过验证。历史上 CVE-2015-9235(jsonwebtoken)、CVE-2022-23529(多个 Node 库)都源自这里。服务端必须强制白名单算法,例如 `algorithms: ['RS256']`,禁止让 Token 告诉你用哪个算法。本工具在 UI 上同时显示 Header.alg 与你实际选择的算法,并在两者不一致时高亮提示——这就是在为「客户端不该信 Header.alg」做演示。
Privacy & Security
本 JWT 工作台 100% 在你的浏览器内运行,依赖浏览器原生 Web Crypto API。你粘贴的 Token、Header、Payload、Signature、HMAC Secret、RSA/ECDSA 私钥、生成的密钥对、所有签名验签计算都只在本地完成,不经过任何服务器,不写日志、不做埋点、不缓存 Token。我们没有能力访问你的输入(页面加载完成后即可断网使用)。安全最佳实践:永远不要把生产环境的长期 Token 与生产私钥贴到任何在线工具上,本工具适合调试、联调、学习、生成测试 Token,但**生产 Secret / 私钥应在本地受控环境处理**。
Supported Video Formats
| Format | MIME | Browser support | When to use |
|---|---|---|---|
| HS256 / HS384 / HS512 | HMAC + SHA-256/384/512 | 全平台 | 对称密钥算法。签发与验签用同一 Secret,简单高效,适合服务集群内部可信环境。Secret 至少 32 字节随机数。 |
| RS256 / RS384 / RS512 | RSASSA-PKCS1-v1_5 + SHA-2 | Web Crypto API | 最常见的非对称算法。签发用私钥,验签用公钥。多数 OIDC IdP、API 网关、企业 SSO 默认使用 RS256。 |
| PS256 / PS384 / PS512 | RSA-PSS + SHA-2 | Web Crypto API | RSA-PSS 是 RS256 的更新版,安全性更高。AWS SigV4、AWS Cognito、新晋 OIDC IdP 倾向使用。saltLength 必须显式指定。 |
| ES256 / ES384 / ES512 | ECDSA + P-256/P-384/P-521 | Web Crypto API | 椭圆曲线签名。签名长度短(ES256 仅 64 字节)、性能好,JWT 体积更小。Apple Sign in with Apple 默认使用 ES256。 |
| EdDSA(Ed25519) | Ed25519 / Ed448 | Web Crypto API | 下一代高性能签名算法。确定性签名(同一消息同一密钥始终同结果),无随机数风险,OAuth 2.1 推荐算法。 |
Authoritative References
- 安全字串比較
- 二進位轉換
- 凱薩密碼
- 摩斯密碼
- 十六進位轉換
- 影片轉 Base64
- Base64 轉影片
- 圖片轉 Base64
- Base64 轉圖片
- 文字轉 Base64
- Base64 轉文字
- 檔案雜湊校驗
- 檔案轉 Base64
- Base64 轉檔案
- 音訊轉Base64
- Base64轉音訊
- AES 加密解密
- DES 加密解密
- Base32 編碼解碼
- Base58 編碼解碼
- Base64 編碼
- Base64 解碼
- Base64 比較
- Base64 拆分
- Base64 多行合併
- Base64 格式化
- Base64 格式檢查
- Base64 批次編碼
- Base64 批次解碼
- Base64 清理
- Base64 填充處理
- Base64 長度統計
- Base64 轉十六進位
- Base64 DataURL 轉換
- Base64-Hex 互轉
- Base85 編解碼器
- HMAC 生成與驗證
- PBKDF2 金鑰派生
- MD5 雜湊
- SHA-256 雜湊
- SHA1 雜湊
- SHA512 雜湊
- JWT 工具
- HTML 實體編碼解碼
- Unicode 跳脫
- URL 編碼
- URL Safe Base64
- MIME Base64
- Java 混淆
- JS 混淆
- PHP 混淆
- Python 混淆