Different Results in Go and Pycrypto when using AES-CFB

前端 未结 5 1146
遇见更好的自我
遇见更好的自我 2021-01-02 05:33

I am adding a go application to an already existing python codebase. I\'ve been having trouble dealing with encryption between the languages. This is using go 1.2.1 and Pyth

相关标签:
5条回答
  • 2021-01-02 05:44

    It seems that the cipher can be made compatible to Go's crypto/cipher if we change segment_size of AES object from the default 8 to AES.block_size*8 (which is 128), like this:

    Crypto.Cipher.AES.new(
                key=password, 
                mode=Crypto.Cipher.AES.MODE_CFB, 
                IV=iv,
                segment_size=AES.block_size*8
    )
    
    0 讨论(0)
  • 2021-01-02 05:52

    Research on the current system has revealed that our python system uses CFB8 (8 bit segments). Go does not support this out of the box, but the source code used in the current CFBDecrypter / CFBEncrypter looks like it can be adapted fairly easily.

    0 讨论(0)
  • 2021-01-02 05:52

    I found that easiest way to deal with this from Python side is to use M2Crypto library.

    Final code looks like:

    import M2Crypto.EVP
    
    iv = ciphertext[:16]
    ciphertext = ciphertext[16:]
    
    cipher = M2Crypto.EVP.Cipher('aes_256_cfb', t, iv, 0)
    text = cipher.update(ciphertext)
    print text
    

    Works perfect without need to change something in Go.

    0 讨论(0)
  • 2021-01-02 05:56

    i solve by adapt python code like this (golang encode and python decode):

    # golang encode
    padNum := len(data) % 16
    if padNum != 0 {
        for i := 0; i < 16-padNum; i++ {
            data = append(data, ',')
        }
    }
    
    # python decode
    cipher = AES.new(key=self.key, mode=AES.MODE_CFB, IV=iv,segment_size=128)
    
    0 讨论(0)
  • 2021-01-02 06:05

    If anyone is looking for Go implementation of CFB mode with segment size = 8 you can use this:

    import "crypto/cipher"
    
    // CFB stream with 8 bit segment size
    // See http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
    type cfb8 struct {
        b         cipher.Block
        blockSize int
        in        []byte
        out       []byte
    
        decrypt bool
    }
    
    func (x *cfb8) XORKeyStream(dst, src []byte) {
        for i := range src {
            x.b.Encrypt(x.out, x.in)
            copy(x.in[:x.blockSize-1], x.in[1:])
            if x.decrypt {
                x.in[x.blockSize-1] = src[i]
            }
            dst[i] = src[i] ^ x.out[0]
            if !x.decrypt {
                x.in[x.blockSize-1] = dst[i]
            }
        }
    }
    
    // NewCFB8Encrypter returns a Stream which encrypts with cipher feedback mode
    // (segment size = 8), using the given Block. The iv must be the same length as
    // the Block's block size.
    func newCFB8Encrypter(block cipher.Block, iv []byte) cipher.Stream {
        return newCFB8(block, iv, false)
    }
    
    // NewCFB8Decrypter returns a Stream which decrypts with cipher feedback mode
    // (segment size = 8), using the given Block. The iv must be the same length as
    // the Block's block size.
    func newCFB8Decrypter(block cipher.Block, iv []byte) cipher.Stream {
        return newCFB8(block, iv, true)
    }
    
    func newCFB8(block cipher.Block, iv []byte, decrypt bool) cipher.Stream {
        blockSize := block.BlockSize()
        if len(iv) != blockSize {
            // stack trace will indicate whether it was de or encryption
            panic("cipher.newCFB: IV length must equal block size")
        }
        x := &cfb8{
            b:         block,
            blockSize: blockSize,
            out:       make([]byte, blockSize),
            in:        make([]byte, blockSize),
            decrypt:   decrypt,
        }
        copy(x.in, iv)
    
        return x
    }
    
    0 讨论(0)
提交回复
热议问题