遵循AES CFB兼容性 [英] Go AES CFB compatibility
问题描述
我正在开发依赖于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 []字节)(加密[]字节){
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/ 提供了一种简单的测试方法这个。
感谢
Steve
Key:00000000000000000000000000000000
IV:00000000000000000000000000000000
Enc:66
In:00
Out:00
http://play.golang。 org / p / wl2y1EE6lK
它与您提供的工具匹配,然后是:
键:00000000000000000000000000000000
IV:00000000000000000000000000000000
Enc:66e94b
In:000000
输出:000000
http:// play。 golang.org/p/DNC42m2oU5
其中不符合工具:
6616f9
http://aes.online-domain-tools.com/link / 63687gDNzymApefh /
第一个字节匹配,表示可能存在反馈问题。
在第二次查看CFB模式后,Go的代码看起来很好,所以可能是其他的实现是错误的。 b $ b
I am developing a client-side app in Go that relies on AES CFB. The server-side is written in C. My problem is that Go's AES CFB implementation appears to differ from many others (including OpenSSL). I wrote this to test my theory:-
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))
}
When this is run, it appears to work perfectly, however, if the encrypted bytes are pasted into another AES implementation and decrypted using the same key and IV, the plaintext is corrupted (except for the first Byte). http://aes.online-domain-tools.com/ provides a simple means to test this. Any suggestions why this might be happening and how I can resolve it?
Thanks Steve
I investigated this with the following inputs because I was unsure of the bit/byte order for both inputs and outputs :
Key: 00000000000000000000000000000000
IV: 00000000000000000000000000000000
Enc: 66
In: 00
Out: 00
http://play.golang.org/p/wl2y1EE6lK
Which matches the tool you provided, and then this :
Key: 00000000000000000000000000000000
IV: 00000000000000000000000000000000
Enc: 66e94b
In: 000000
Out: 000000
http://play.golang.org/p/DNC42m2oU5
Which doesn't match the tool :
6616f9
http://aes.online-domain-tools.com/link/63687gDNzymApefh/
The first byte matches, which indicates there may be a feedback issue.
So I checked the Go package's code and I think there is a bug here :
func (x *cfb) XORKeyStream(dst, src []byte) {
for len(src) > 0 {
if x.outUsed == len(x.out) {
x.b.Encrypt(x.out, x.next)
x.outUsed = 0
}
if x.decrypt {
// We can precompute a larger segment of the
// keystream on decryption. This will allow
// larger batches for xor, and we should be
// able to match CTR/OFB performance.
copy(x.next[x.outUsed:], src)
}
n := xorBytes(dst, src, x.out[x.outUsed:])
if !x.decrypt {
copy(x.next[x.outUsed:], dst) // BUG? `dst` should be `src`
}
dst = dst[n:]
src = src[n:]
x.outUsed += n
}
}
EDIT
After a second look at CFB mode it seems that Go's code is fine, so yeah it may be the other implementations are wrong.
这篇关于遵循AES CFB兼容性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!