英文:
Go AES128 without IV
问题
我正在尝试解密一些没有初始化向量(IV)的AES128数据。Go语言提供了一种使用IV解密的简单方法,但我无法弄清楚如何在不使用IV的情况下进行解密。以下是我目前的代码:
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
if len(data)%aes.BlockSize != 0 {
panic("密文长度不是块大小的倍数")
}
fmt.Printf("解密结果:\n%s\n", data)
所以我正在努力弄清楚如何使用block
进行解密。
谢谢...
英文:
I am trying to decypher some AES128 data that does not have the IV. Go provides easy way to decypher with IV, but I cannot figure out how to go about not using the IV. So here what I have so far:
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
if len(data)%aes.BlockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
fmt.Printf("Decyphered:\n%s\n", data)
So I am struggling to figure out how to decypher using the block.
Thanks...
答案1
得分: 2
我假设你在这里使用的是CBC模式,但CFB模式应该也可以工作。
请注意,由于IV不被视为机密,通常将其作为方便起见附加到密文本身之前。
由于这些模式处理IV的方式,如果使用了错误的IV,你只会丢失第一个明文块。如果实际的IV存在,你会在明文输出的开头解密出随机数据,因此尝试使用空IV进行解密不会有任何损害。但是,如果没有原始IV,你无法恢复第一个块(除非使用暴力破解)。
以下是示例代码:
key := []byte("YELLOW SUBMARINE")
plaintext := []byte("exampleplaintext that is longer than a single block and some pad")
if len(plaintext)%aes.BlockSize != 0 {
panic("plaintext not multiple of block size")
}
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// IV需要是唯一的,但不需要是安全的。因此,通常将其包含在密文的开头。
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext)
// 现在使用错误的IV进行解密
iv = make([]byte, 16)
// 如果你想要正确的IV,在这种情况下,我们可以从密文中提取它
// iv = ciphertext[:aes.BlockSize]
// ciphertext = ciphertext[aes.BlockSize:]
if len(ciphertext)%aes.BlockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
mode = cipher.NewCBCDecrypter(block, iv)
newPlaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(newPlaintext, ciphertext)
fmt.Printf("%s\n", newPlaintext)
希望对你有帮助!
英文:
I'm assuming you're using CBC here, but CFB mode should work the same.
Note that since the IV isn't considered secret, it's often prepended to the ciphertext itself for convenience.
Because of the way these modes handle the IV, if you use the incorrect IV you only lose the first block of plaintext. If the actual IV is there, you end up decrypting random data at the beginning of your plaintext output, so it doesn't hurt to simply try to decrypt it with an empty IV. Without the original IV though, you cannot get back that first block (short of using brute-force).
key := []byte("YELLOW SUBMARINE")
plaintext := []byte("exampleplaintext that is longer than a single block and some pad")
if len(plaintext)%aes.BlockSize != 0 {
panic("plaintext not multiple of block size")
}
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext)
// Now Decrypt with wrong IV
iv = make([]byte, 16)
// If you wanted the correct IV, in thise case we could pull it from the ciphertext
//iv = ciphertext[:aes.BlockSize]
//ciphertext = ciphertext[aes.BlockSize:]
if len(ciphertext)%aes.BlockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
mode = cipher.NewCBCDecrypter(block, iv)
newPlaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(newPlaintext, ciphertext)
fmt.Printf("%s\n", newPlaintext)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论