AES_CTR加密
这个在你看过前两篇(ECB,CBC)后还是非常简单的,几句话就讲明白了
AES-CTR 模式就是把 AES 当作流密码生成器使用:每个块用“计数器块(Nonce + Counter)”做 AES 单块加密,生成 16 字节的密钥流,再和明文异或得到密文;解密时同样用 AES 加密计数器块生成密钥流,再 XOR 密文即可得到明文。注意,明文本身从不进入 AES,加密和解密完全相同
就是把我们的计数器进行aes加密,但是明文不进行aes,我们把被加密后的计数器块和明文进行异或处理,得到最终密文
流程:
- 准备一个 8 字节 nonce 和一个 8 字节计数器 counter,拼成 16 字节计数器块
- 将计数器块 AES 加密 → 得到 16 字节的密钥流(keystream)
- 将密钥流与明文块 XOR → 得到密文块
- 计数器自增,处理下一块明文,重复步骤 2~3
特点:
- 每块独立 → 可以并行加密
- 不需要填充,明文任意长度
- 密文长度 = 明文长度
- AES 只处理计数器块,明文不进入 AES
- 现代标准推荐(CTR/GCM、TLS1.3、QUIC 等
func AES_CTR(key []byte, nonce []byte, data []byte) []byte {
if len(key) != 16 {
panic("key must be 16 bytes")
}
if len(nonce) != 8 {
panic("nonce must be 8 bytes")
}
// 生成 round keys
roundKeys := AES_keyExpansion(key)
out := make([]byte, len(data))
counter := uint64(0)
block := make([]byte, 16) // nonce(8) + counter(8)
copy(block[:8], nonce)
for i := 0; i < len(data); i += 16 {
// 设置计数器
binary.BigEndian.PutUint64(block[8:], counter)
counter++
// keystream = AES_encryptBlock(counter_block)
keystream := AES_encryptBlock(block, roundKeys)
// 处理可能不足 16 字节的块
end := i + 16
if end > len(data) {
end = len(data)
}
// XOR 生成密文或明文
for j := i; j < end; j++ {
out[j] = data[j] ^ keystream[j-i]
}
}
return out
}