我正在开发一个依赖AES CFB的Go客户端应用程序。服务器端是用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实现中并使用相同的密钥和IV进行解密,则明文将被破坏(除了第一个字节)。http://aes.online-domain-tools.com/提供了一种简单的测试方法。有什么建议吗?为什么会发生这种事?我该如何解决?
谢谢史蒂夫
发布于 2014-08-25 18:22:47
(首先,一个强制性警告: CFB模式是本土密码的标志。除非您正在实现OpenPGP,否则您应该使用一种AE模式,如AES-GCM或NaCl的秘箱。如果你被迫使用CFB模式,我希望你至少是在用HMAC认证密文。)
撇开这一点不说,围棋中的CFB模式是支持OpenPGP的。(OpenPGP在不同的地方使用经过调整的CFB模式(称为OCFB )和标准CFB模式。)Go OpenPGP代码似乎至少与其他实现互操作。
Nick是正确的,测试向量丢失在Go crypto包中。测试来自OpenPGP代码,但是包应该是独立的,所以我将使用第一节F.3.13中的测试向量向crypto/cipher添加测试。
我对任何差异的来源最好的猜测是,CFB是由块大小参数化的。这通常是两个比特数的幂,直到底层密码的块大小。如果未指定块大小,则通常将其视为密码块大小,这就是Go代码所做的。见1,第6.3节。一个更友好的解释是由2。
在黑暗时代(90年代末),当人们在密码丢失时担心密码重新合成之类的事情时,就使用了小块大小。如果另一个实现是使用CFB1或CFB8,那么它将与Go的CFB模式和许多其他的实现有很大的不同。(Go的代码不支持较小的块大小。)
1
2
https://stackoverflow.com/questions/25462314
复制相似问题