douju9272 2014-08-23 13:15
浏览 63
已采纳

兼容AES CFB

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

  • 写回答

2条回答 默认 最新

  • douhu2370 2014-08-23 14:43
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line