KeyGenerator.io

JWT 密钥生成器

HS256、HS384、HS512 用的 HMAC 签名密钥,在你的浏览器里生成。不联网,不记录,不上传。

0 位熵

密钥长度
编码

空格键 换一个,C 复制。密钥由本机的 crypto.getRandomValues 生成,页面不加载任何外部资源。

这串密钥是怎么生成的

用 HS256、HS384 或 HS512 签发的令牌,验证时用的是同一把密钥。它不是密码:没有人要输入它,也没有人需要记住它,更不该念得出来。它是一串随机字节,存放在环境变量或密钥管理服务里,唯一的任务就是让人猜不到。

这里的字节直接取自 crypto.getRandomValues,也就是浏览器的密码学安全随机数生成器,再以十六进制或 Base64 写出。整条路径上没有时间戳、没有计数器,也没有 Math.random。选 256 位会得到 32 个随机字节,384 位是 48 个,512 位是 64 个 —— 长度对应该算法所用的哈希。

全部在你自己的设备上完成。页面加载后不发出任何网络请求,所以屏幕上这串密钥从未在别处存在过,也不会传到任何地方。刷新一下就永远消失。

常见问题

JWT 密钥要多长才够?

至少要和签发算法的哈希输出一样长:HS256 是 32 字节(256 位),HS384 是 48 字节,HS512 是 64 字节。HMAC 会把超过分组长度的密钥再哈希一次压回来,所以 200 字节并不会比 64 字节实质更强。真正的风险在于比这更短。

十六进制和 Base64 哪个更安全?

一样。它们是同一串随机字节的两种写法 —— 32 个字节写成十六进制是 64 个字符,写成 Base64 大约 44 个字符,强度完全相同。用你的库预期的那种即可。如果这个值要经过配置文件或 shell 脚本,十六进制更保险,因为它只含 0-9 和 a-f。

什么时候该用 Base64URL?

Base64URL 把 + 和 / 换成 - 和 _,并去掉填充字符,因此可以直接放进 URL、查询字符串或文件名而不必再转义。其他场合用标准 Base64 就好。JWT 本身确实采用 Base64URL 编码,但那说的是令牌,不是用来签发它的密钥。

可以直接拿密码或口令当密钥吗?

可以,而这正是 HMAC 签名最常见的破口。好记的句子所携带的熵远低于它的长度看起来的样子,而攻击者只要手上有一个有效令牌,就能离线以硬件极限的速度逐个试出候选密钥,没有任何次数限制拦得住。请用随机字节。

在网页里生成密钥安全吗?

这完全取决于这个页面能不能把它送出去,而这件事你可以自己核实,不必只是相信。打开浏览器开发者工具切到「网络」面板,然后随便生成几次:这个页面加载之后不发出任何请求。它背后没有服务端,因为它根本没有服务端可言。

密钥该放在哪里?

放在环境变量里,有密钥管理服务就放进去。绝对不要放进代码仓库 —— 一旦提交进 git,即使之后删掉也还留在历史记录里,而历史会被克隆、被 fork、被备份。如果已经提交过,唯一有效的补救是换一把。

多久该轮换一次?

按一个你真能坚持的周期,并在怀疑泄露时立刻更换。实际操作上的阻力在于:轮换会让所有用旧密钥签发的令牌失效。需要在不强制登出的前提下轮换的系统,通常会设一段并行期 —— 用新密钥签发,同时接受新旧两把验证,之后再下线旧的。

这个也能用在 RS256 或 ES256 上吗?

不行。那两者是非对称的:用私钥签发、用对应的公钥验证,需要的是一对密钥而不是共享密钥。这个页面生成的是对称的 HMAC 密钥,也就是 HS 系列所使用的。如果签发方和验证方是不同的组织,通常反而该选非对称算法。

你们看得到我生成的密钥吗?

看不到,也没有任何东西能看到。这个页面是一份静态 HTML,样式和脚本都内嵌其中;送到你的浏览器之后,不再加载任何东西,也不发送任何东西。没有统计分析、没有字体、没有第三方脚本,也没有任何可以记录的服务器。