转到 AES CFB 兼容性

标签 go cryptography aes

我正在使用 Go 开发一个依赖于 AES CFB 的客户端应用程序。服务器端是用 C 编写的。我的问题是 Go 的 AES CFB 实现似乎与许多其他实现(包括 OpenSSL)不同。我写这个是为了检验我的理论:-

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)
  return
}

func decrypt_aes_cfb(encrypted, key, iv []byte) (plain []byte) {
  block, err := aes.NewCipher(key)
  if err != nil {
    panic(err)
  }
  plain = make([]byte, len(encrypted))
  stream := cipher.NewCFBDecrypter(block, iv)
  stream.XORKeyStream(plain, encrypted)
  return
}

func main() {
  plain := []byte("Hello world.....")
  key := []byte("01234567890123456789012345678901")
  iv := []byte("0123456789012345")
  enc := encrypt_aes_cfb(plain, key, iv)
  dec := decrypt_aes_cfb(enc, key, iv)
  fmt.Println("Key: ", hex.EncodeToString(key))
  fmt.Println("IV:  ", hex.EncodeToString(iv))
  fmt.Println("Enc: ", hex.EncodeToString(enc))
  fmt.Println("In:  ", hex.EncodeToString(plain))
  fmt.Println("Out: ", hex.EncodeToString(dec))
}

运行时,它似乎运行良好,但是,如果将加密字节粘贴到另一个 AES 实现中并使用相同的 key 和 IV 解密,则明文已损坏(第一个字节除外)。 http://aes.online-domain-tools.com/ 提供了一种简单的方法来测试它。为什么会发生这种情况以及我该如何解决有什么建议吗?

谢谢 史蒂夫

最佳答案

(首先,强制性警告:CFB 模式是本土加密的标志。除非您正在实现 OpenPGP,否则您应该使用 AES-GCM 或 NaCl 的 secretbox 等 AE 模式。如果您被迫使用 CFB 模式,我希望您至少使用 HMAC 验证密文。)

除此之外,Go 中的 CFB 模式用于 OpenPGP 支持。 (OpenPGP 在不同的地方同时使用称为 OCFB 的经过调整的 CFB 模式,标准 CFB 模式。)Go OpenPGP 代码似乎至少可以与其他实现互操作。

Nick 是正确的,Go crypto 包中缺少测试向量。测试来自 OpenPGP 代码,但包应该是独立的,因此我将使用 [1] 的 F.3.13 节中的测试向量将测试添加到 crypto/cipher

我对任何差异来源的最佳猜测是 CFB 由 block 大小参数化。这通常是不超过底层密码 block 大小的两位数的幂。如果未指定 block 大小,则通常将其视为密码 block 大小,这是 Go 代码所做的。参见 [1],第 6.3 节。 [2]给出了更友好的解释。

小块大小在黑暗时代(90 年代后期)被使用,当时人们担心面对密文丢失时密码重新同步之类的事情。如果另一个实现使用 CFB1 或 CFB8,那么它将与 Go 的 CFB 模式和许多其他模式有很大不同。 (Go 的代码不支持更小的 block 大小。)

[1] http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf

[2] http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29

关于转到 AES CFB 兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25462314/

相关文章:

c# - CngKeyBlobFormat 支持的实际格式是什么?

aes - 在没有身份验证标签的情况下使用 Python 解密 AES GCM

delphi - 使用 SynCrypto 的 AES 加密问题

javascript - Google CryptoJS AES 结果太长 1 个区 block

java - aproximately 给定大小的安全随机数

go - 如何在 Golang 中创建目录?

Go 1.0.2 zlib 压缩时如何提高速度

go - 我应该如何在 golang 中编码用于 Google Voice 识别的音频流?

java - 需要一个示例 - 使用 Microsoft Crypto API 解密 Java 中的字符串

amazon-s3 - 连接到 S3