KeyGenerator.io

AES 密钥生成器

128、192、256 位的 AES 随机密钥,在你的浏览器里生成。不联网,不记录,不上传。

0 位熵

密钥长度
编码

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

这把密钥是怎么生成的

AES 密钥是一段长度固定的随机字节:AES-128 是 16 个,AES-192 是 24 个,AES-256 是 32 个。它和密码不同,没有长度上下限可以权衡 —— 算法只接受这三种长度之一,而其中每一个二进制位都必须无法被猜到。

这些字节直接取自 crypto.getRandomValues,也就是浏览器的密码学安全随机数生成器,再以十六进制或 Base64 写出。整条路径上没有时间戳、没有计数器,也没有 Math.random。两种写法承载的是同一串字节,挑你的库或密钥存储服务要的那种即可。

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

常见问题

该选哪个长度?

没有特殊约束就选 AES-256 —— 不是因为 128 位会被破解,而是因为更长的密钥几乎不增加成本,还能让这个问题以后不必再争。AES-128 对暴力破解依然完全安全,在没有 AES 硬件加速的设备上还明显更快。AES-192 存在、可用,但因为用的人太少,部分库和硬件路径对它的支持反而不如另外两种。

AES-256 的强度是 AES-128 的两倍吗?

不是,差距是 2^128 倍而不是 2 倍。但这两个数字都早已越过「暴力破解毫无意义」的界线:数到 2^128 所需的能量超出整个地球的预算,无论你设想什么硬件。真实系统的破口从来不在密钥长度,而在于 nonce 重复使用、密钥直接由口令推导、以及密钥和它保护的数据存在同一个地方。

IV 就是密钥吗?

不是,而混淆这两者是 AES 最常见的错误。密钥是长期保存的机密;IV(在 GCM 模式下叫 nonce)是每条消息各自一份的值,完全不是机密,通常就明文附在密文旁边一起传输。每条消息都要生成新的 IV;密钥则生成一次后长期保留。

每条消息都要换一把密钥吗?

不用。一把密钥可以加密很多条消息,前提是每条消息都有自己的 IV 或 nonce。绝对不能重复的是同一把密钥下的 nonce —— 在 GCM 模式下重复使用会泄漏两段明文的异或,并让攻击者能够伪造消息,那是彻底失守而不是稍微变弱。惯例做法是每条消息随机生成一个 96 位的 nonce。

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

不能直接用。口令既短又取自很小的空间,而 AES 密钥必须与随机数据无法区分。如果输入非得由人记住,就让它经过密钥派生函数 —— Argon2id、scrypt,或迭代次数足够高的 PBKDF2 —— 再把输出当密钥。把口令用 SHA-256 哈希一次确实会得到 32 个字节,但那不是 32 个字节的不可预测性。

该用 GCM 还是 CBC?

绝大多数情况选 GCM。它在加密之外同时提供认证,密文被篡改会被检测到,而不是悄悄解出一堆垃圾再被你的代码当成真的。CBC 本身完全不提供完整性保护,必须另外搭配 MAC,而且组合顺序还要正确 —— 这正是最容易无声出错的那类细节。

十六进制还是 Base64?

两者是同一串字节:256 位密钥写成十六进制是 64 个字符,写成 Base64 是 44 个字符,强度完全相同。用接收方预期的格式即可 —— 云上的密钥管理服务和各语言的库通常要 Base64,而配置文件、命令行参数,以及任何会经过 shell 的地方用十六进制更保险,因为它只含 0-9 和 a-f。

密钥该放在哪里?

有密钥管理服务就放进去,没有的话放在环境变量或不进版本控制的机密文件里。绝对不要和它保护的密文放在一起 —— 密钥若和数据存在同一个数据库、同一份备份或同一个仓库里,那份存储一旦被复制,保护就等于不存在。另外要注意:更换 AES 密钥意味着要把数据重新加密,所以轮换需要事先规划,不是设个定时任务就完事。

在浏览器里生成加密密钥安全吗?

只有在这个页面无法把它送出去的前提下才安全,而这件事你可以核实,不必只是相信。打开开发者工具停在「网络」面板,然后随便生成几次:页面加载之后不发出任何请求。它背后没有服务器可以接收任何东西,也没有统计分析或第三方脚本可以外泄。