KeyGenerator.io

AES 密钥生成器

128、192、256 位的 AES 随机密钥,在你的浏览器里生成。

0 位熵

密钥长度
编码

按 空格键 换一个,C 复制。密钥由本机的 crypto.getRandomValues 生成。

生成 AES-256 十六进制密钥

保留 256 位设置、选择十六进制,然后复制密钥。得到的是 32 个随机字节,以 64 个十六进制字符表示。如果接收系统要求 Base64,改选 Base64 即可。

AES 密钥随机字节十六进制字符Base64 字符
AES-128163224
AES-192244832
AES-256326444

这把密钥是怎么生成的

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 就是密钥吗?

不是。密钥是长期保存的机密;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 密钥意味着要把数据重新加密,所以轮换需要事先规划,不是设个定时任务就完事。