【问题标题】:Golang AES CFB - Mutating IVGolang AES CFB - 变异 IV
【发布时间】:2014-10-20 05:38:58
【问题描述】:

我在 Go 中编写了一个客户端应用程序,它需要与服务器端的 C 程序进行交互。客户端执行 AES CFB 加密,服务器解密。不幸的是,服务器端有一个重用初始化向量的错误。它尝试根据以下内容进行 3 次解密操作:-
key1, iv
key2, iv
key3, iv

由于this issue,iv 实际上在解密操作之间进行了修改。我现在的问题是如何使用 Go 在客户端重现这种行为。

通过在下面的 encrypt 函数中插入一个 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))
}

【问题讨论】:

  • 无法修复服务器代码?
  • 也许,服务器端可以及时修复,但这样做会破坏向后兼容性。
  • “由于这个问题,iv 实际上在解密操作之间被修改了。我现在的问题是如何使用 Go 在客户端重现这种行为” - 不要重现破碎的行为。解决问题。由于您有记忆问题,因此它可能不是跨语言的确定性问题。

标签: encryption go openssl


【解决方案1】:

沿着你暗示的路径走有点丑陋,并且在实现更改时容易中断。

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

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

但是,有一个更简单的方法!连接纯文本输入,以便第二个的流从第一个结尾的 IV 开始(依此类推)。

Playground Example

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

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

【讨论】:

  • 啊,非常感谢 JimB。你不仅给了我一个答案,你让我意识到我不需要它。 :)
  • @SteveCrook 在 StackOverflow 上感谢的常用方法是投票,当然也接受您提出的问题的答案。看来您还没有接受任何答案。您可以通过点击答案左侧的 V 标记来做到这一点。
猜你喜欢
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
相关资源
最近更新 更多