# AES 测试向量：浏览器与加密库验证实验室

> 使用 CryptoJS、Web Crypto 和 HSM Kit 浏览器工具复现 NIST AES-128、AES-192、AES-256、ECB 与 CBC 已知答案向量。

Canonical: https://hsmkit.com/zh/guides/aes-test-vectors-browser-validation/

Last updated: 2026-09-23

已知答案测试用于回答一个精确问题：当密钥、模式、IV、填充规则和明文字节完全确定时，实现是否生成预期密文？HSM Kit 发布统一格式的 AES 验证集，便于逐字节比较浏览器代码、命令行工具、应用库和 HSM 集成结果。

## 下载验证数据集

完整数据可从 [AES 测试向量 JSON](/test-vectors/aes.json) 下载，其中包含来源链接、算法参数、预期密文和本项目采用的验证方法。

这些数值来自公开的 NIST 标准，并非随机生成。HSM Kit 的原创工作是统一的数据结构、可执行回归测试、浏览器复现流程和本文的差异诊断方法。

## 包含的向量

| ID | 算法 | 模式 | 输入长度 | 主要来源 |
|---|---|---|---:|---|
| `fips-197-aes-128-ecb` | AES-128 | ECB | 16 字节 | FIPS 197 附录 C.1 |
| `fips-197-aes-192-ecb` | AES-192 | ECB | 16 字节 | FIPS 197 附录 C.2 |
| `fips-197-aes-256-ecb` | AES-256 | ECB | 16 字节 | FIPS 197 附录 C.3 |
| `sp800-38a-aes-128-cbc` | AES-128 | CBC | 64 字节 | SP 800-38A F.2.1 |

所有向量都使用原始十六进制字节并且**不使用填充**。这一点很重要：许多库默认启用 PKCS#7，因此会额外产生一个密文分组。

## 快速验证 AES-128

使用以下 FIPS 197 数值：

```text
算法: AES-128
模式: ECB
填充: 无
密钥: 000102030405060708090A0B0C0D0E0F
明文: 00112233445566778899AABBCCDDEEFF
密文: 69C4E0D86A7B0430D8CDB78070B4C55A
```

打开 [AES 中文加密工具](/zh/aes-encryption/)，选择 AES-128、ECB 和十六进制输入，然后输入密钥和明文。结果必须与上述密文完全一致，解密也必须恢复原始明文。

## CBC 多分组验证

SP 800-38A 向量包含四个分组，除了 AES 原语外还会验证 CBC 链接过程：

```text
密钥: 2B7E151628AED2A6ABF7158809CF4F3C
IV:   000102030405060708090A0B0C0D0E0F
```

JSON 文件中提供了完整的 64 字节明文与密文。IV 改变一位会改变第一个解密分组；某个密文分组改变一位，会影响对应明文分组以及下一个分组的相同比特位置。这些特征有助于定位 IV 和链接处理错误。

## 独立复现方法

HSM Kit 自动测试执行两类独立验证：

1. 使用 CryptoJS、显式 `NoPadding` 和指定模式加密全部向量。
2. 使用与浏览器兼容的 Web Crypto API 再次验证 AES-CBC 向量。Web Crypto 的 CBC 会强制填充，因此测试会逐字节验证前四个 NIST 密文分组，并单独断言末尾新增的 16 字节填充分组。

预期密文不是页面运行时计算后再自我比较，而是保存在公开数据集中，并在测试期间逐字节核对。CryptoJS 结果或 Web Crypto 的 NIST 密文前缀不一致都会导致构建失败。

## 结果不一致的常见原因

### 文本与十六进制字节混淆

文本 `0011` 是四个 ASCII 字节（`30 30 31 31`），十六进制值 `0011` 只有两个字节。必须确认 API 接收的是文本、Hex 解码结果、Base64 还是字节数组。

### 自动填充

标准向量已经按分组对齐。在 API 允许时，应关闭 PKCS#7、PKCS#5、零填充或 ISO 7816 填充。多出 16 字节密文通常表示库自动添加了完整填充分组。Web Crypto AES-CBC 始终进行填充，因此应比较与 NIST 长度相同的密文前缀，或使用支持显式 NoPadding 的库获得完全一致的输出。

### IV 编码错误

CBC 的 IV 长度是 16 字节。如果把 32 个 Hex 字符本身当成 ASCII 传入，而不是先解码，就会得到 32 字节值和完全不同的结果。

### 模式不一致

ECB 不需要 IV，各分组独立加密；CBC 会将明文分组与前一密文分组异或。GCM 和 CTR 使用计数器，不能复现 CBC 或 ECB 向量。

### 密钥长度推断错误

应根据密钥字节数判断 AES-128、AES-192 或 AES-256。对密码进行截断、哈希或补零会得到另一把密钥。

### 输出封装

某些 API 会在结果前加入 IV、盐值、版本字段或认证标签。已知答案测试应比较原始密文字节，而不是库特有的封装格式。

## 互操作检查清单

- 加密前将所有十六进制字段解码为字节。
- 显式指定模式和填充。
- 按字节确认密钥和 IV 长度。
- 比较时忽略 Hex 大小写和分隔符差异。
- 同时验证加密与解密。
- 将协议封装与原语测试分开。
- 报告不一致时记录库、平台和版本。

## 安全边界

通过已知答案测试只能证明某一配置能够复现预期字节，不代表协议设计安全、密钥生成可靠或实现能够抵抗侧信道攻击。ECB 仅用于验证 AES 原语，不应保护多分组机密数据。

新系统的认证加密选择可继续阅读 [AES-GCM 与 AES-CBC 对比](/zh/guides/aes-gcm-vs-cbc/) 和 [AES IV 与 Nonce 重用](/zh/guides/aes-iv-nonce-reuse/)。
