Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python AES-CTR与Golang不兼容_Python_Go_Encryption_Aes_Pycryptodome - Fatal编程技术网

Python AES-CTR与Golang不兼容

Python AES-CTR与Golang不兼容,python,go,encryption,aes,pycryptodome,Python,Go,Encryption,Aes,Pycryptodome,我在Ubuntu 16.04上使用Python2.7和pycryptodome 3.6.6以及Golang1.10.4 我选择的加密算法是AES-CTR-128。但是Python和Golang加密的数据有不同的结果。因此,这两种语言编写的应用程序之间的通信存在问题 这是我的工具: Python: #coding=utf-8 from __future__ import absolute_import import binascii from Crypto.Cipher import AES f

我在Ubuntu 16.04上使用Python2.7和pycryptodome 3.6.6以及Golang1.10.4

我选择的加密算法是AES-CTR-128。但是Python和Golang加密的数据有不同的结果。因此,这两种语言编写的应用程序之间的通信存在问题

这是我的工具:

Python:

#coding=utf-8

from __future__ import absolute_import
import binascii
from Crypto.Cipher import AES
from Crypto.Util import Counter

def hexlify(binary):
    return binascii.hexlify(binary)

class AES_CTR(object):
    def __init__(self, key, iv):
        assert len(key) == 16
        assert len(iv) == 16
        ctr = Counter.new(128)
        self.aes = AES.new(key, AES.MODE_CTR, counter=ctr)

    def encrypt(self, plain_data):
        return self.aes.encrypt(plain_data)

    def decrypt(self, encrypted_data):
        return self.aes.decrypt(encrypted_data)

if __name__ == '__main__':
    aes = AES_CTR('abcdef0123456789', '0123456789abcdef')
    print hexlify(aes.encrypt("hello")) #print '9b1a038478'
    print hexlify(aes.encrypt("hello")) #print '8751ea0448'
    print hexlify(aes.encrypt("world")) #print 'b6aa7c286b'
戈兰

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "encoding/hex"
    "fmt"
)


type AESCipher struct {
    iv []byte
    stream cipher.Stream
}

func NewAESCipher(key []byte, iv []byte) *AESCipher {
    if (len(iv) != 16 || len(key) != 16) {
        panic("iv length or key length error")
    }
    block, err := aes.NewCipher(key)
    if (err != nil) {
        panic(err)
    }
    return &AESCipher {
        iv: iv,
        stream: cipher.NewCTR(block, iv),
    }
}

func (cipher *AESCipher) Encrypt(buffer []byte) []byte {
    encrypted := make([]byte, len(buffer))
    cipher.stream.XORKeyStream(encrypted, buffer)
    return encrypted
}

func (cipher *AESCipher) Decrypt(buffer []byte) []byte {
    decrypted := make([]byte, len(buffer))
    cipher.stream.XORKeyStream(decrypted, buffer)
    return decrypted
}

func main() {
    iv := []byte("0123456789abcdef")
    key := []byte("abcdef0123456789")
    cipher := NewAESCipher(key, iv)

    encrypted1 := cipher.Encrypt([]byte("hello"))
    fmt.Println(hex.EncodeToString(encrypted1)) // print '94ee8ac46a'
    encrypted2 := cipher.Encrypt([]byte("hello"))
    fmt.Println(hex.EncodeToString(encrypted2)) // print 'b36d48ad7e'
    encrypted3 := cipher.Encrypt([]byte("world"))
    fmt.Println(hex.EncodeToString(encrypted3)) // print '7302071a9c'
}
问题解决了

根据,pycryptodome的默认实现不正确。我们可以更改
计数器
,使其按预期工作

ctr = Counter.new(128, initial_value=bytes_to_long(iv))

现在它工作得很好。

您可以通过根本不使用
计数器来简化代码,例如:

试试这个:

ctr = Counter.new(128, initial_value= int.frombytes(iv.encode(),'little'))
IV始终作为整数值和字节格式的键传递。 检查上述链接中的文档

ctr = Counter.new(128, initial_value= int.frombytes(iv.encode(),'little'))