Python AES CTR实现

Python AES CTR实现,python,cryptography,pycrypto,Python,Cryptography,Pycrypto,我正在尝试自己实现CTR模式,目前仅使用pycrypto中的AES内置函数进行解密。这意味着我不应该使用mode=AES.mode\u CTR。然而,我知道使用AES.MODE_CTR会更简单,但我这样做是作为一种学习体验 我不确定如何使用AES作为PRF,以便在CTR加密算法中使用它 我做错了什么? 非视差版本 from Crypto.Cipher import AES ciphers = ["69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f

我正在尝试自己实现CTR模式,目前仅使用pycrypto中的AES内置函数进行解密。这意味着我不应该使用mode=AES.mode\u CTR。然而,我知道使用AES.MODE_CTR会更简单,但我这样做是作为一种学习体验

我不确定如何使用AES作为PRF,以便在CTR加密算法中使用它

我做错了什么? 非视差版本

from Crypto.Cipher import AES

ciphers = ["69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f7520d1cbbb20fc3" + \
    "88d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329", \
    "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa" + \
    "0e311bde9d4e01726d3184c34451"]

key     = "36f18357be4dbd77f050515c73fcf9f2"  

class IVCounter(object):
    def __init__(self, value):
        self.value = value

    def increment(self):
        # Add the counter value to IV
        newIV = hex(int(self.value.encode('hex'), 16) + 1)

        # Cut the negligible part of the string
        self.value = newIV[2:len(newIV) - 1].decode('hex') # for not L strings remove $ - 1 $ 
        return self.value

    def __repr__(self):
        self.increment()
        return self.value

    def string(self):
        return self.value

class CTR():
    def __init__(self, k):
        self.key = k

    def __strxor(self, a, b):     # xor two strings of different lengths
        if len(a) > len(b):
            return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
        else:
            return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

    def __split_len(self, seq, lenght):
        return [seq[i:i+lenght] for i in range(0, len(seq), lenght)]

    def __AESdecryptor(self, k, cipher):
        decryptor = AES.new(k, AES.MODE_ECB)

        return decryptor.decrypt(cipher)

    def decrypt(self, cipher):
        # Split the CT in blocks of 16 bytes
        blocks = self.__split_len(cipher.decode('hex'), 16)

        # Takes the initiator vector
        self.IV = IVCounter(blocks[0])
        blocks.remove(blocks[0])    

        # Message block 
        msg = []

        # Decrypt
        for b in blocks:
            aes = self.__AESdecryptor(self.key.decode('hex'), self.IV.string())
            msg.append(self.__strxor(b, aes))

            self.IV.increment()

        return ''.join(msg)

def main():
    decryptor = CTR(key)
    for c in ciphers:
        print 'msg = ' + decryptor.decrypt(c)

if __name__ == '__main__':
    main()
这段代码应该和下面的代码一样,但它并没有像应该的那样解码

import Crypto.Util.Counter
ctr_e = Crypto.Util.Counter.new(128, initial_value=long(IV.encode('hex'), 16))
decryptor = AES.new(key.decode('hex'), AES.MODE_CTR, counter=ctr_e)
print decryptor.decrypt(''.join(blocks))
AES CTR模式使用AES的前向转换进行加密和解密。也就是说,在这两种情况下,对计数器进行加密,然后执行异或运算。当我说“前向转换”时,我的意思是您总是执行AES_Encryptcounter,而从不执行AES_Decryptcounter

对纯文本和密码文本都执行异或运算,不管是加密还是解密。文本XOR encryptcounter是加密或解密操作。这是一个流密码

self.IV.string不是AES密钥。它是在密钥下加密的值。一旦加密,它将与{plain cipher}文本异或

AES CTR模式使用AES的前向转换进行加密和解密。也就是说,在这两种情况下,对计数器进行加密,然后执行异或运算。当我说“前向转换”时,我的意思是您总是执行AES_Encryptcounter,而从不执行AES_Decryptcounter

对纯文本和密码文本都执行异或运算,不管是加密还是解密。文本XOR encryptcounter是加密或解密操作。这是一个流密码


self.IV.string不是AES密钥。它是在密钥下加密的值。一旦加密,它就会与{plain cipher}文本异或。

我终于让这段代码运行良好,错误非常简单。我不应该使用decrypt AES函数,我应该使用encrypt AES函数,正如noloader所说的,我在第一时间并没有很好地理解他。感谢所有提供帮助的人,以下是固定代码:

from Crypto.Cipher import AES

ciphers = ["69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f7520d1cbbb20fc3" + \
    "88d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329",      \
    "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa" + \
    "0e311bde9d4e01726d3184c34451"]

key     = "36f18357be4dbd77f050515c73fcf9f2"  

class IVCounter(object):
    def __init__(self, value):
    self.value = value

    def increment(self):
        # Add the counter value to IV
        newIV = hex(int(self.value.encode('hex'), 16) + 1)

        # Cut the negligible part of the string
        self.value = newIV[2:len(newIV) - 1].decode('hex') # for not L strings remove $ - 1 $ 
        return self.value

    def __repr__(self):
        self.increment()
        return self.value

    def string(self):
        return self.value

class CTR():
    def __init__(self, k):
        self.key = k.decode('hex')

    def __strxor(self, a, b):     # xor two strings of different lengths
        if len(a) > len(b):
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
        else:
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

    def __split_len(self, seq, lenght):
        return [seq[i:i+lenght] for i in range(0, len(seq), lenght)]

    def __AESencryptor(self, cipher):
        encryptor = AES.new(self.key, AES.MODE_ECB)
        return encryptor.encrypt(cipher)

    def decrypt(self, cipher):
        # Split the CT into blocks of 16 bytes
        blocks = self.__split_len(cipher.decode('hex'), 16)

        # Takes the initiator vector
        self.IV = IVCounter(blocks[0])
        blocks.remove(blocks[0])    

        # Message block 
        msg = []

        # Decrypt
        for b in blocks:
        aes = self.__AESencryptor(self.IV.string())
        msg.append(self.__strxor(b, aes))

        self.IV.increment()

        return ''.join(msg)

def main():
    decryptor = CTR(key)
    for c in ciphers:
    print 'msg = ' + decryptor.decrypt(c)

if __name__ == '__main__':
    main()

我终于让这段代码正常工作了,错误很简单。我不应该使用decrypt AES函数,我应该使用encrypt AES函数,正如noloader所说的,我在第一时间并没有很好地理解他。感谢所有提供帮助的人,以下是固定代码:

from Crypto.Cipher import AES

ciphers = ["69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f7520d1cbbb20fc3" + \
    "88d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329",      \
    "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa" + \
    "0e311bde9d4e01726d3184c34451"]

key     = "36f18357be4dbd77f050515c73fcf9f2"  

class IVCounter(object):
    def __init__(self, value):
    self.value = value

    def increment(self):
        # Add the counter value to IV
        newIV = hex(int(self.value.encode('hex'), 16) + 1)

        # Cut the negligible part of the string
        self.value = newIV[2:len(newIV) - 1].decode('hex') # for not L strings remove $ - 1 $ 
        return self.value

    def __repr__(self):
        self.increment()
        return self.value

    def string(self):
        return self.value

class CTR():
    def __init__(self, k):
        self.key = k.decode('hex')

    def __strxor(self, a, b):     # xor two strings of different lengths
        if len(a) > len(b):
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
        else:
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

    def __split_len(self, seq, lenght):
        return [seq[i:i+lenght] for i in range(0, len(seq), lenght)]

    def __AESencryptor(self, cipher):
        encryptor = AES.new(self.key, AES.MODE_ECB)
        return encryptor.encrypt(cipher)

    def decrypt(self, cipher):
        # Split the CT into blocks of 16 bytes
        blocks = self.__split_len(cipher.decode('hex'), 16)

        # Takes the initiator vector
        self.IV = IVCounter(blocks[0])
        blocks.remove(blocks[0])    

        # Message block 
        msg = []

        # Decrypt
        for b in blocks:
        aes = self.__AESencryptor(self.IV.string())
        msg.append(self.__strxor(b, aes))

        self.IV.increment()

        return ''.join(msg)

def main():
    decryptor = CTR(key)
    for c in ciphers:
    print 'msg = ' + decryptor.decrypt(c)

if __name__ == '__main__':
    main()

是的,是的。对此我很抱歉。我会试试codereview。谢谢!没问题,dasho,祝你的代码顺利运行。我已经把这个问题放在了代码审查上,那里的人暂停了帖子,让我把它放在堆栈溢出上。我有点困惑,但我认为代码审查只是为了工作代码。@owlstead我们可以在这里调试代码,只要问题的范围合理,我不确定它是否在这里。@owlstead我可以编辑我的问题吗?我在考虑如何将AES作为伪随机函数用于CTR加密算法?是的,是的。对此我很抱歉。我会试试codereview。谢谢!没问题,dasho,祝你的代码顺利运行。我已经把这个问题放在了代码审查上,那里的人暂停了帖子,让我把它放在堆栈溢出上。我有点困惑,但我认为代码审查只是为了工作代码。@owlstead我们可以在这里调试代码,只要问题的范围合理,我不确定它是否在这里。@owlstead我可以编辑我的问题吗?我在考虑如何将AES用作伪随机函数,以便在CTR加密算法中使用它?noloader,很抱歉,我第一次没有理解您的解决方案。正如你所说,我修改了我的代码,现在可以正常工作了。非常感谢你!空载者,很抱歉我第一次没有理解你的解决方案。正如你所说,我修改了我的代码,现在可以正常工作了。非常感谢你!