gpt4 book ai didi

Golang (Go) AES CBC 密文由于某种原因被填充了 16 个 0x00 字节

转载 作者:行者123 更新时间:2023-12-05 05:40:04 24 4
gpt4 key购买 nike

我正在 Golang (Go) 中测试 AES 256 CBC 实现。

plaintext: {"key1": "value1", "key2": "value2"}

因为明文是 36 B 并且需要是 block 大小 (16 B) 的倍数,所以我用 12 个随机字节手动填充到 48 B。我知道这不是最安全的方法,但我只是在测试,我会找到更好的生产设置方法。

输入:

plaintext: aaaaaaaaaaaa{"key1": "value1", "key2": "value2"}
AES 256 key: b8ae2fe8669c0401fb289e6ab6247924
AES IV: e0332fc2a9743e4f

here 中提取但稍作修改的代码摘录:

block, err := aes.NewCipher(key)
if err != nil {
fmt.Println("Error creating a new AES cipher by using your key!");
fmt.Println(err);
os.Exit(1);
}

ciphertext := make([]byte, aes.BlockSize+len(plaintext))

mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)

fmt.Printf("%x\n", ciphertext)
fmt.Println("len(ciphertext):",len(ciphertext))

CipherText = PlainText + Block - (PlainText MOD Block)

这个等式给出了 CBC 的密文长度。

因此,ciphertext := make([]byte, aes.BlockSize+len(plaintext)) 行满足此要求,因为我的明文总是被填充为 block 大小的倍数。

问题:

通过 Go,我得到以下密文: caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c7400000000000000000000000000000000

无论明文长度如何,我的密文末尾总是有 16 个 0x00 字节。

如果我用在线 AES 计算器做同样的事情,我会得到这个密文: caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c74ccd202bac41937be75731f23796f1516

前 48 个字节 caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c74是相同的。但我遗漏了最后 16 个字节。

This说:

It is acceptable to pass a dst bigger than src, and in that case,CryptBlocks will only update dst[:len(src)] and will not touch therest of dst.

但为什么会这样呢?密文的长度需要比明文的长度长,在线 AES 计算器证明了这一点。

最佳答案

在线工具结果的密文,如果是明文:

aaaaaaaaaaaa{"key1": "value1", "key2": "value2"}

用 PKCS#7 填充,发布的 key 和 IV 是 UTF8 编码的。由于明文的大小(48 字节)已经是 block 大小(AES 为 16 字节)的整数倍,因此根据 PKCS#7 padding 的规则填充一个完整的 block 。 , 产生 64 字节的明文和密文。

从问题中不清楚使用的是哪种在线工具,但可以使用任何可靠的加密工具重建发布的密文,例如网络厨师,s。 this online calcualtion . Cyber​​Chef 默认为 AES/CBC 应用 PKCS#7 填充。


发布的代码会产生不同的密文,因为:

  1. 未应用 PKCS#7 填充。这使得密文缩短了一个 block (即最后一个 block ccd202bac41937be75731f23796f1516 丢失了)。
  2. 为密文分配了大小为aes.BlockSize + len(plaintext) 字节。这会导致分配的大小过大 aes.BlockSize 字节(即密文末尾包含 16 个 0x00 值)。

因此,要使 Go 代码生成与在线工具相同的密文,1. 必须添加 PKCS#7 填充,并且 2. 必须只有 len(plaintext) 字节的大小分配给密文。

以下代码是一个可能的实现(对于 PKCS#7,使用 pkcs7pad 填充):

import (
...
"github.com/zenazn/pkcs7pad"
)
...
key := []byte("b8ae2fe8669c0401fb289e6ab6247924")
iv := []byte("e0332fc2a9743e4f")
plaintext := []byte("aaaaaaaaaaaa{\"key1\": \"value1\", \"key2\": \"value2\"}")
plaintext = pkcs7pad.Pad(plaintext, aes.BlockSize) // 1. pad the plaintext with PKCS#7
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext := make([]byte, len(plaintext)) // 2. allocate len(plaintext)
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
fmt.Printf("%x\n", ciphertext) // caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c74ccd202bac41937be75731f23796f1516

请注意,由于 PKCS#7 填充,不再需要使用 a 进行显式填充。


上述代码中使用的 static IV 是一个漏洞,因为它会导致 key /IV 对的重用,这是不安全的。因此,在实践中,通常会为每次加密生成一个随机 IV。 IV 不是 secret 的,是解密所必需的,并且通常与密文连接在一起。在解密端,将IV和密文分开,用于解密。
由于 IV 的大小对应于 block 大小,因此必须为密文分配 aes.BlockSize + len(plaintext) 的大小,这等于原始代码中的大小。可能这不是偶然的,而是在设计时考虑了随机 IV,但后来没有实现。一个后续的实现是:

import (
...
"crypto/rand"
"io"
"github.com/zenazn/pkcs7pad"
)
...
key := []byte("b8ae2fe8669c0401fb289e6ab6247924")
plaintext := []byte("{\"key1\": \"value1\", \"key2\": \"value2\"}")
plaintext = pkcs7pad.Pad(plaintext, aes.BlockSize)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
_, err = io.ReadFull(rand.Reader, iv) // create a random IV
if err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext)

输出的前 16 个字节对应于(随机)IV,其余字节对应于实际密文。

关于Golang (Go) AES CBC 密文由于某种原因被填充了 16 个 0x00 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72499124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com