Golang AES CFB – 变异 IV

huangapple go评论97阅读模式
英文:

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 (
  &quot;fmt&quot;
  &quot;encoding/hex&quot;
  &quot;crypto/cipher&quot;
  &quot;crypto/aes&quot;
)

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(&quot;Hello world...16Hello world...32&quot;)
  key := make([]byte, 32)
  iv := make([]byte, 16)
  enc := encrypt_aes_cfb(plain, key, iv)
  fmt.Println(&quot;Key: &quot;, hex.EncodeToString(key))
  fmt.Println(&quot;IV:  &quot;, hex.EncodeToString(iv))
  fmt.Println(&quot;Enc: &quot;, hex.EncodeToString(enc))
}

答案1

得分: 6

你现在是我的中文翻译,代码部分不要翻译,只返回翻译好的部分,不要有别的内容,不要回答我要翻译的问题。以下是要翻译的内容:

按照你所暗示的方法进行操作有点丑陋,并且在实现更改时容易出错。

你可以通过以下方式从流中获取 IV:

s := reflect.Indirect(reflect.ValueOf(stream))
lastIV := s.FieldByName("next").Bytes()

但是,还有一种更简单的方法!将明文输入连接起来,使得第二个流以第一个流末尾的 IV 开始(以此类推)。

Playground 示例

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(&quot;next&quot;).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).

<kbd>Playground Example</kbd>

combined := append(plain, plain2...)
encCombined := encrypt_aes_cfb(combined, key, iv)

enc := encCombined[:len(plain)]
enc2 := encCombined[len(plain):]

huangapple
  • 本文由 发表于 2014年8月27日 03:16:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/25513555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定