首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Golang (Go) AES CBC密文因某种原因被填充16 0x00字节

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

Stack Overflow用户
提问于 2022-06-04 10:46:02
回答 1查看 1.3K关注 0票数 3

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

代码语言:javascript
运行
复制
plaintext: {"key1": "value1", "key2": "value2"}

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

投入:

代码语言:javascript
运行
复制
plaintext: aaaaaaaaaaaa{"key1": "value1", "key2": "value2"}
AES 256 key: b8ae2fe8669c0401fb289e6ab6247924
AES IV: e0332fc2a9743e4f

这里提取的代码摘录,但做了一些修改。

代码语言:javascript
运行
复制
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 +块- (PlainText MOD块)

这个方程给出了CBC的密文长度。

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

问题:

使用Go,我得到以下密文:caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c7400000000000000000000000000000000

无论明文的长度如何,我总是在密文末尾得到160x00字节。

如果我对在线AES计算器做同样的操作,我会得到以下密文:caf8fe667f4087e1b67d8c9c57fcb1f56b368cafb4bfecbda1e481661ab7b93d87703fb140368d3034d5187c53861c74ccd202bac41937be75731f23796f1516

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

说:

传递大于src的dst是可以接受的,在这种情况下,CryptBlocks将只更新dst:len(src),而不会触及dst的其余部分。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-04 14:06:04

如果明文为明文,则在线工具的密文:

代码语言:javascript
运行
复制
aaaaaaaaaaaa{"key1": "value1", "key2": "value2"}

是用PKCS#7填充的,发布的密钥和IV是UTF8编码的。由于明文的大小(48字节)已经是块大小的整数倍数(对于AES是16字节),因此根据PKCS#7填充的规则填充完整的块,从而生成64字节的明文和密文。

从使用哪一种在线工具的问题上还不清楚,但是可以使用任何可靠的加密工具(如CyberChef,s. 这个在线计算 )来重构已发布的密文。默认情况下,CyberChef为AES/CBC应用PKCS#7填充。

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

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

因此,要使Go代码生成与联机工具相同的密文,必须添加PKCS#7填充,2.必须为密文分配len(plaintext)字节大小。

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

代码语言:javascript
运行
复制
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进行显式填充。

上面代码中使用的静态IV是一个漏洞,因为它会导致密钥/IV对的重用,这是不安全的。因此,在实践中,通常会为每次加密生成一个随机IV。IV不是秘密的,需要解密,并且通常与密文连接。在解密端,IV和密文被分离并用于解密。

由于IV的大小对应于块大小,所以必须为密文分配aes.BlockSize + len(plaintext)大小,这等于原始代码中的大小。这可能不是偶然的,设计时考虑的是随机IV,但后来没有实现。由此产生的执行情况是:

代码语言:javascript
运行
复制
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,其余字节对应于实际的密文。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72499124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档