使用方法
- 选「加密」,在明文框里粘贴内容(示例已预填
柳泉工具 2026 演示文本)。 - 填口令(示例
demo-pass-2026)与迭代次数(示例310000)。口令不要用生日或短数字,迭代次数越高越安全但越慢。 - 点「开始加密」或按
Ctrl/Cmd+Enter,等页面算出结果后点「复制结果」把整段Lq.封装拿走。 - 要还原时切到「解密」,把
Lq.整段粘进第一个框,口令填成加密时那一个,点「开始解密」。 - 点「重置」回到示例条件;迭代次数改动后同一段密文解不出来了(盐与密钥都绑定了当次参数),这属于正常行为。
这个在线文本加密工具AES加密能解决什么问题
在线文本加密工具AES加密解决的是「需要一段只有特定口令能读回去的文本」,典型是:把配置里的连接串、一段含手机号的记录、一段内部备注先加密再贴进工单、聊天或issue;或者给自己的一段草稿做口令保护,防的是「随手一翻就能看到」。
选 GCM 而不是 CBC 是本页的技术核心。CBC 加密后不校验完整性,密文被改动一个 bit,解密时会得到一段乱码而没有任何提示——你无法区分「口令错了」与「数据被改了」。GCM(Galois/Counter Mode)在加密的同时算出一个 16 字节的认证标签,解密时先验标签,不过就整体失败。代价是明文长度固定可见(改了长度标签就对不上),这一点在正文「边界与精度」里讲清楚。
必须说清本页不做什么:它不能替代传输安全。把明文走 HTTP 提交、或者把密钥写在同一个 HTML 文件里,加密环节等于白做。本页的价值是「一段文本在离开你屏幕时已经被锁住」,不是「端到端安全通道」。要评估口令本身够不够强请用密码熵值计算器;要算暴力破解需要多久请用 Brute力时间计算器;要处理的是摘要校验而不是加密请用 SHA256加密。要把二进制值转成 URL 安全的短文本请用 Base64URL编码解码。
原理与规则说明:为什么用 WebCrypto,而不是自己写 AES
- 调用的 API:
crypto.subtle.importKey('raw', ..., 'PBKDF2', false, ['deriveKey'])导入口令素材,crypto.subtle.deriveKey()派生 AES-GCM 密钥,crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data)加密、decrypt()解密。全部来自 W3C Web Cryptography API Level 2,对应规范是 W3C 的Web Cryptography API Level 2,底层实现对接 OpenSSL 等成熟密码库。 - 为什么不自实现:AES 的 S 盒、密钥扩展、GCM 的 GHASH 与 CTR 计数器,任何一处写错都可能产生「看起来能加能解、实际不安全」的结果,而且不写测试根本发现不了。WebCrypto 是浏览器原生实现、由浏览器厂商维护,且在 Secure Context 下硬件加速。自实现的最大风险不是「解不开」,而是悄悄退化成弱算法。本页只调用原生函数,不含任何手写密码学。
- 密钥长度为什么固定 256 位:
deriveKey的length传 256。AES-GCM在 WebCrypto 里支持 128/192/256 三种密钥长度,这里取最大的 256 位,没有额外成本(软件实现下 128 与 256 的速度差很小),也不用向用户暴露「选 128 还是 256」这种无意义的选择。 - IV 为什么必须是 12 字节:GCM 的 IV 长度规范允许 1 到 2^64−1 字节,但 96 位(12 字节)是 NIST SP 800-38D 明确推荐的唯一非特殊长度。原因很具体:IV 只有 96 位时才能直接拼在 32 位计数器后面当作初始计数器块用;其它长度需要先对 IV 跑一次 GHASH 才能得到初始计数器,多一遍运算,正好抵消 GCM 相对 CBC 的速度优势。所以本页面
randomValues(new Uint8Array(12))固定 12 字节——实测传 8 字节会直接抛OperationError,不是「慢一点」而是根本不允许。 - 盐 16 字节的理由:盐的作用是让同一个口令在不同记录上派生出不同密钥,杜绝彩虹表。RFC 8018 建议盐长度不小于 8 字节,OWASP 建议不小于 16 字节。这里取 16 字节:短于 16 撞库空间变小,长于 16 只是线性增加 PBKDF2 的每轮耗时(盐参与每轮哈希)。盐不保密,它明文放在封装里——它的价值是「唯一性」,不是「秘密」。
- 迭代次数 310000 的取舍:这是本页面最需要解释的参数。PBKDF2 的迭代次数与耗时成线性关系(实测 10000 次 2.0 ms、100000 次 16.8 ms、310000 次 50.5 ms、600000 次 107.4 ms,310000 / 10000 = 24.08 倍耗时,理论值 31 倍,差异来自首次调用与常量项)。OWASP 对 PBKDF2-HMAC-SHA256 的当前推荐是 600000 次,本页默认取 310000 是在「安全余量」与「浏览器里等 0.05 秒还是 0.1 秒」之间取的折中。次数太低会让离线爆破成本骤降,太高则页面要空等。你可以在输入框里试不同数值,耗时变化是线性的,这正是 PBKDF2 作为「刻意设计的慢函数」的体现。
- 认证标签 16 字节是写死的:GCM 的标签长度可选 4/8/12/13/14/15/16 字节,但 WebCrypto 只开放 16 字节这一个选项,无法配置。所以密文长度 = 明文字节数 + 16,这是一个可以提前算准的确定值——正文对照表就靠它推算每个长度的密文大小。
- 遵循的标准:AES 本身由 FIPS 197 定义;GCM 模式由 NIST SP 800-38D 定义;PBKDF2 由 RFC 8018 定义;WebCrypto API 由 W3C 定义。Base64 编码用 RFC 4648 的标准字母表。四个标准分属四层,本页每一层都直接对应一个函数调用。
- 为什么解密失败只给一个笼统报错:实测用错误口令解密时,WebCrypto 抛的是
OperationError,message 为The operation failed for an operation-specific reason,不区分「口令错」与「密文被篡改」。这是 AEAD 的刻意设计:如果报错时能区分两者,攻击者就能用一条密文当「校验器」去爆破口令。代价是使用者分不清自己的两个失误,所以本页的报错文案会把两个可能原因都写出来,并给出排查顺序。
完整示例(数值仅作演示)
示例条件与工具默认值完全一致:明文 柳泉工具 2026 演示文本、口令 demo-pass-2026、迭代 310000。
- 明文 UTF-8 逐字核算:
柳泉工具4 个汉字 × 3 字节 = 12,1 字节,20264 字节,1 字节,演示文本4 个汉字 × 3 字节 = 12,合计 30 字节(14 个字符)。注意按字符数直觉算会得到 14,和真实字节数差 16。 - 密文 = 30 + 16(认证标签)= 46 字节,实测确认。
- 容器 = 盐 16 + IV 12 + 密文 46 = 74 字节;三段分别 Base64 后为 24 + 16 +
ceil(46/3)*4 = 64字符,再加前缀Lq.(3 字符)与 2 个点号,封装总长 109 字符。盐段末尾 1 个=,IV 段无填充(12 能被 3 整除),密文段(46 % 3 = 1)末尾 2 个=。 - 两次加密结果不同:实测两次的 IV 分别得到 16 字符的不同串,密文也不相同。这不是缺陷——同一个密钥下 IV 必须唯一,否则 GCM 会退化成 CTR 模式并泄露明文异或关系。所以判断一次加密是否成功的依据是能否解开,不是密文是否一致。
- 换短口令或换迭代次数后,同一段封装都解不出原文:因为 PBKDF2 的盐与迭代次数参与密钥派生,任一不同都得到完全不同的密钥,而 GCM 验签必然失败。所以加密后请连口令一起妥善保存,别指望凭「大致记得」的口令能解开。
以上字节数与长度均为按算法规则实算的结果,任何一段真实密文的字符都会不同。
输入范围与对照表
输入范围:明文上限 1 MB(1048576 字符,由 maxlength 限定);口令 1 ~ 200 字符;迭代次数 1000 ~ 1000000。下表是 24 组不同明文长度对应的密文与封装长度,前 12 行直接显示。
| 明文内容 | 字符数 | UTF-8 字节 | 密文字节 | 封装 Base64 | 相对明文膨胀 |
|---|---|---|---|---|---|
| a | 1 | 1 | 17 | 69 | +6800% |
| ab | 2 | 2 | 18 | 69 | +3350% |
| abc | 3 | 3 | 19 | 73 | +2333% |
| abcd | 4 | 4 | 20 | 73 | +1725% |
| hello | 5 | 5 | 21 | 73 | +1360% |
| hello world | 11 | 11 | 27 | 81 | +636% |
| 柳泉 | 2 | 6 | 22 | 77 | +1183% |
| 柳泉工具 | 4 | 12 | 28 | 85 | +608% |
| 柳泉工具 2026 | 9 | 17 | 33 | 89 | +424% |
| 柳泉工具 2026 演示文本 | 14 | 30 | 46 | 109 | +263% |
| a × 40 | 40 | 40 | 56 | 121 | +202% |
| 中文长文案 39 字 | 39 | 117 | 133 | 225 | +92% |
| 1234567890 | 10 | 10 | 26 | 81 | +710% |
| test@test.com | 13 | 13 | 29 | 85 | +554% |
| https://example.com/a?b=c | 25 | 25 | 41 | 101 | +304% |
| 订单号 20260303120000123 | 21 | 27 | 43 | 105 | +289% |
| 张三 13800138000 北京市朝阳区 | 21 | 37 | 53 | 117 | +216% |
| VEVENT 三行文本 | 34 | 38 | 54 | 117 | +208% |
| a × 80 | 80 | 80 | 96 | 173 | +116% |
| 今天天气不错 ☀️ 适合出门 | 14 | 38 | 54 | 117 | +208% |
| 😀😃😄😁😆 | 5 | 20 | 36 | 93 | +365% |
| a × 100 | 100 | 100 | 116 | 201 | +101% |
| 英文长句 × 3 | 134 | 134 | 150 | 245 | +83% |
| 密钥是 K7#mQ2$vX9!pL4&wR8^nT6 | 26 | 32 | 48 | 109 | +241% |
体积膨胀的两个固定成本——这是短文本加密看起来「夸张」的真正原因:
| 成本项 | 字节 | Base64 后字符 | 说明 |
|---|---|---|---|
| 盐(salt) | 16 | 24 | 每次随机,明文携带 |
| IV | 12 | 16 | 每次随机,明文携带 |
| 认证标签 | 16 | 24 | 固定开销,与明文长度无关 |
| Base64 膨胀 | — | +33.3% | (4/3 − 1),把二进制塞进文本的必然代价 |
| 前缀 + 分隔符 | 3 | 5 | Lq. 加 2 个点号 |
| 合计固定开销 | 47 | 69 | 28 字节随机 + 16 字节标签 + 前缀分隔符 |
边界与精度
- 安全上下文是硬前提:
crypto.subtle只在 Secure Context 下暴露,也就是 HTTPS、localhost与127.0.0.1。通过http://访问一个非 localhost 的域名,或直接用file://打开本地文件,window.isSecureContext为false,crypto.subtle是undefined。页面的检测式是typeof crypto === 'undefined' || typeof crypto.subtle === 'undefined',命中时给出明确提示而不是静默失败。本页不提供任何降级实现——手写 AES 正是前面说的「悄悄退化成弱算法」的主要来源,宁可不可用也不给假实现。 - 明文上限 1 MB:
subtle.encrypt()需要把整个明文一次性搬进内存,超大文本会让标签页长时间无响应。本页在长度检查处就拦下。1 MB 明文经封装后约 1398169 字符——这类体量已经不适合走文本渠道,应该考虑分块或改走文件加密。 - 迭代次数边界 1000 ~ 1000000:低于 1000 时 PBKDF2 提供的拉伸几乎可以忽略,等于把口令哈希做成单轮 SHA-256;高于 1000000 时单次操作会占用主线程数百毫秒到数秒,手工拖动滑块时能明显感到页面发木。1000 也并非绝对禁止(便于与旧系统互操作),但安全上不推荐。
- 明文长度可见:GCM 是流模式,密文长度 = 明文长度 + 16,没有任何隐藏。传 30 字节和传 31 字节的密文长度不同,观察者能推断出明文的字节数——包括它是不是汉字(每字 3 字节)。对隐藏「大致有多长」没有需求的话这不是问题;真要隐藏长度需要额外填充(如把明文补到固定块),本页不做,因为那会让格式复杂化而收益有限。
- 两条不设防的地方:一是口令长度,PBKDF2 不限制也不补强,短口令(如
123)无论迭代多少次都易被字典爆破,PBKDF2 只能拖慢不能变强;二是不防重放,同一段封装可以被反复提交,解密方无法分辨这是新请求还是旧请求重放。这两点要靠口令强度与外层协议解决,不是换加密模式能补的。 - 不承担传输安全的职责:本页产出的密文可以贴在工单、聊天、issue 里,粘贴者看不到明文。但如果在传输前明文就已经离开过你的设备,加密救不回来。也不要为了「看起来安全」把口令写在同一个页面的输入框默认值里——本页的示例口令是明文写在 HTML 里的演示值,实际使用请换成你自己的、且不要复用任何其它站点的密码。
常见问题
点「开始加密」提示 crypto.subtle 未定义,是浏览器不支持吗?
多数情况不是不支持,而是不在安全上下文。crypto.subtle 只在 HTTPS、localhost、127.0.0.1 下暴露;用 http:// 访问非 localhost 域名,或 file:// 打开本地文件,都会让它变成 undefined。在地址栏左侧看 window.isSecureContext 即可确认。真正不支持的浏览器极少(WebCrypto 从 2016 年起已在主流浏览器普及)。若确认环境无误仍失败,请记住在线文本加密工具AES加密没有降级实现这一点。
解密提示失败,是口令错还是密文被改了?怎么区分?
页面不能区分,这是 GCM 的设计而非缺陷。实测 WebCrypto 在这两种情况下都只抛 OperationError,消息是 The operation failed for an operation-specific reason。原因很实在:如果解密失败时能告诉你是口令错,攻击者就能拿一条已知密文当「口令校验器」反复试口令了。请按这个顺序排查:一、口令是否与加密时完全一致(含大小写与首尾空格);二、迭代次数是否还是当时那个值(改了必然失败);三、Lq. 整段是否复制完整(少一个字符或丢结尾的 = 都不行);四、是否误把别的密文粘进来了。
为什么同一段明文加密两次,结果不一样?
因为每次都重新随机生成了盐和 IV。实测两次的 IV 完全不同,密文也随之不同。这是必须的正确行为:同一个密钥下如果 IV 重复,GCM 会退化成 CTR 模式,同一密钥的两个明文会泄露异或关系。判断加密是否成功要看能否用口令解回原文,不要用「密文是否和上次一样」来判断。相应地,密文不方便做去重比对——那正是哈希(摘要)的用途,请用 SHA256加密。
为什么短文本加密后长度涨了好几倍?
因为有 47 字节固定开销:盐 16 + IV 12 + 认证标签 16,再加 Lq. 前缀与 2 个点号共 5 个字符。加密 1 个字符 a 得到 17 字节密文,封装后 69 字符,相对明文膨胀 6800%。这部分开销不随明文增长而摊薄——明文越长相对膨胀越低,134 字节的英文长句只涨 83%,1 MB 明文则是 33.3%(趋近 Base64 本身的膨胀率)。要减小传输体积请直接传二进制而不是 Base64,本页面向的是文本场景。
迭代次数调高有什么用?调多少合适?
作用是线性拉高离线爆破成本。实测 10000 次 2.0 ms、100000 次 16.8 ms、310000 次 50.5 ms、600000 次 107.4 ms——次数翻倍耗时也翻倍,因为 PBKDF2 就是刻意设计的慢函数。OWASP 对 PBKDF2-HMAC-SHA256 的当前推荐是 600000 次,本页默认 310000 是在「留足余量」与「浏览器里少等一会儿」之间的折中。调高它不会让弱口令变强,只会让攻击者的每条猜测也变慢;口令本身太弱时,再高的迭代数也只是把几分钟的破解变成几小时。选口令请先用密码熵值计算器估一下熵值够不够。
这能替代 HTTPS 吗?
不能,这是本页最需要强调的边界。本页解决的是「一段文本在离开屏幕前被锁住」,不解决传输通道是否可读。如果你的明文是通过 HTTP 发出去的,中间人拿到的就是明文,加密这一步完全不起作用。正确用法是:先用 HTTPS 传输,再对确实需要保密的字段额外加密;或者只用 HTTPS 传输、不要自己重复加密。另一个不要做的事是把口令硬编码进页面——本页的示例口令就写在 HTML 里,那是演示值,不是让你照抄的。
为什么 IV 固定 12 字节?我传 8 字节会怎样?
因为 GCM 只有在 IV 恰为 96 位时才能把它直接当作初始计数器块用,其它长度需要先跑一次 GHASH 推导,白白多一遍运算。这 96 位是 NIST SP 800-38D 明确推荐的唯一非特殊长度。实测传 8 字节到 WebCrypto 直接抛 OperationError,不是「慢一点」,而是这个实现只接受 12 字节(以及另外几种更长/更短的长度),所以本页固定生成 12 字节。另外 IV 本身不保密,它明文放在封装里,安全性来自「每次都不一样」而不是「别人看不到」。
这个工具免费吗?明文和口令会上传吗?
免费,无需注册。加密、解密、随机数生成全部在浏览器本地通过 WebCrypto 完成,页面不发任何网络请求,也没有引入任何外部脚本——可以在开发者工具的 Network 面板与 Sources 面板里确认:没有请求,`subtle.encrypt` 不会联网(算法在本地执行)。明文与口令不写 Cookie、不写 localStorage、不做持久化,刷新页面即清空。需要知道的是,浏览器扩展理论上能读到页面里的输入框,这是所有网页工具的共同前提,不是本页特有的问题。
相关工具
- Base64URL编码解码:本页的封装用的是标准 Base64(含
+与/);若要把封装塞进 URL 或 JWT 里,换成 Base64URL 变体更安全。 - SHA256加密:做摘要校验与去重比对,不提供解密能力——与本页的可逆加密用途不同。
- 密码熵值计算器:加密强度完全由口令决定,先估算口令熵值再决定迭代次数。
- Brute力时间计算器:量化 PBKDF2 迭代次数对离线爆破耗时的实际影响,把「调高迭代次数」换算成时间。
- 凯撒密码工具:纯粹的古典代换,几行就能还原——用它对照理解「结构化算法」与「换个字母」的本质差别。
- 在线文本解密工具AES加密:本页的解密方向独立成页,参数与封装格式完全一致,可交叉验证。
- Punycode转换器:处理国际化域名与 IDN 编码时用得上的另一类文本转码,与加密不同层。