英文:
Golang AES CFB - Mutating IV
问题
我正在写一个使用Go语言的客户端应用程序,需要与服务器端的一个C程序进行交互。客户端进行AES CFB加密,服务器进行解密。不幸的是,服务器端存在一个重用初始化向量的错误。它尝试基于以下内容进行3次解密操作:-
key1, iv
key2, iv
key3, iv
由于这个问题,在解密操作之间实际上修改了iv。我的问题是如何在客户端使用Go语言重现这种行为。
通过在下面的加密函数中插入Println语句,我可以看到cfb结构体,我认为它包含了下一个块的修改后的IV,但由于它是一个流接口,我不知道如何将其提取到一个字节切片中。有什么建议吗?
谢谢
package main
import (
"fmt"
"encoding/hex"
"crypto/cipher"
"crypto/aes"
)
func encrypt_aes_cfb(plain, key, iv []byte) (encrypted []byte) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypted = make([]byte, len(plain))
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted, plain)
fmt.Println(stream)
return
}
func main() {
plain := []byte("Hello world...16Hello world...32")
key := make([]byte, 32)
iv := make([]byte, 16)
enc := encrypt_aes_cfb(plain, key, iv)
fmt.Println("Key: ", hex.EncodeToString(key))
fmt.Println("IV: ", hex.EncodeToString(iv))
fmt.Println("Enc: ", hex.EncodeToString(enc))
}
英文:
I've writing a client-side app in Go that needs to interact with a C program on the server-side. The client does an AES CFB encrypt and the server decrypts. Unfortunately the server-side has a bug with reusing an initialization vector. It tries to do 3 decrypt operations based on:-<br>
key1, iv<br>
key2, iv<br>
key3, iv<br>
Due to this issue the iv is actually modified between decrypt operations. My problem now is how to reproduce this behaviour on the client side using Go.
By inserting a Println into the encrypt function below, I can see the cfb struct which, I think, contains the modified IV for the next block but because it's a stream interface, I'm not sure how to extract it into a byte slice. Any suggestions?
Thanks
package main
import (
"fmt"
"encoding/hex"
"crypto/cipher"
"crypto/aes"
)
func encrypt_aes_cfb(plain, key, iv []byte) (encrypted []byte) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypted = make([]byte, len(plain))
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted, plain)
fmt.Println(stream)
return
}
func main() {
plain := []byte("Hello world...16Hello world...32")
key := make([]byte, 32)
iv := make([]byte, 16)
enc := encrypt_aes_cfb(plain, key, iv)
fmt.Println("Key: ", hex.EncodeToString(key))
fmt.Println("IV: ", hex.EncodeToString(iv))
fmt.Println("Enc: ", hex.EncodeToString(enc))
}
答案1
得分: 6
你现在是我的中文翻译,代码部分不要翻译,只返回翻译好的部分,不要有别的内容,不要回答我要翻译的问题。以下是要翻译的内容:
按照你所暗示的方法进行操作有点丑陋,并且在实现更改时容易出错。
你可以通过以下方式从流中获取 IV:
s := reflect.Indirect(reflect.ValueOf(stream))
lastIV := s.FieldByName("next").Bytes()
但是,还有一种更简单的方法!将明文输入连接起来,使得第二个流以第一个流末尾的 IV 开始(以此类推)。
combined := append(plain, plain2...)
encCombined := encrypt_aes_cfb(combined, key, iv)
enc := encCombined[:len(plain)]
enc2 := encCombined[len(plain):]
英文:
Going down the path you're hinting at is a bit ugly, and prone to break when the implementation changes.
You can get the IV from the stream by:
s := reflect.Indirect(reflect.ValueOf(stream))
lastIV := s.FieldByName("next").Bytes()
But, there's an easier way! Concatenate the plain text inputs, so that the stream for the second starts with the IV from the end of the first (and so on).
combined := append(plain, plain2...)
encCombined := encrypt_aes_cfb(combined, key, iv)
enc := encCombined[:len(plain)]
enc2 := encCombined[len(plain):]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论