遵循AES CFB兼容性 [英] Go AES CFB compatibility

查看:185
本文介绍了遵循AES CFB兼容性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发依赖于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 /

第一个字节匹配,表示可能存在反馈问题。

所以我检查了Go软件包的代码,我认为有一个bug
$ b $ pre $ func(x * cfb)XORKeyStream(dst,src [] byte){
for len(src)> 0 {
if x.outUsed == len(x.out){
xbEncrypt(x.out,x.next)
x.outUsed = 0
}

如果x.decrypt {
//我们可以在解密时预先计算
//密钥流的更大部分。这将允许
//更大的批次用于xor,并且我们应该是
//能够匹配CTR / OFB性能。
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`应该是`src`
}
dst = dst [n:]
src = src [n:]
x.outUsed + = n
}
}



编辑

在第二次查看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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆