简体   繁体   English

AES CTR实施

[英]AES CTR implementation

I'm trying to implement CTR mode by myself (only decryption for now), using only AES built-in functions from pycrypto. 我正在尝试仅使用pycrypto的AES内置函数自己实现CTR模式(目前仅解密)。 It means that I'm not supposed to use mode=AES.MODE_CTR. 这意味着我不应该使用mode = AES.MODE_CTR。 However, I know that using AES.MODE_CTR would be more simple, but I'm doing this as a learning experience. 但是,我知道使用AES.MODE_CTR会更简单,但这是我的学习经验。

I'm not sure about how to use AES as a PRF, in order to use it in a CTR cryptography algorithm. 我不确定如何将AES用作PRF,以便在CTR密码算法中使用它。

What am I doing wrong? 我究竟做错了什么? (non-parallalel version) (非平行版本)

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()

This code was supposed to do the same that the code below, but it is not decoding as it should be. 该代码原本应该与下面的代码相同,但是并没有按照原样进行解码。

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))
# Decrypt
for b in blocks:
    aes = self.__AESdecryptor(self.IV.string(), self.key.decode('hex'))
    msg.append(self.__strxor(b, aes))
    self.IV.increment()

return ''.join(msg)

AES CTR mode uses AES's forward transformation for both encryption and decryption. AES CTR模式使用AES的前向转换进行加密和解密。 That is, in both cases, encrypt the counter and then perform the XOR. 也就是说,在两种情况下,都加密计数器,然后执行XOR。 When I say the 'forward transformation', I mean you always perform AES_Encrypt(counter) (and never perform AES_Decrypt(counter) ). 当我说“正向转换”时,我的意思是您始终执行AES_Encrypt(counter) (而从不执行AES_Decrypt(counter) )。

You perform the XOR on both the plain text and the cipher text, irregardless of whether you are encrypting or decrypting. 无论是加密还是解密,都对纯文本和密文执行XOR。 text XOR encrypt(counter) is the encryption or decryption operation. text XOR encrypt(counter)是加密或解密操作。 That's a stream cipher. 那是流密码。

self.IV.string() is not the AES key. self.IV.string()不是AES密钥。 Its the value that is encrypted under the key. 它是在密钥下加密的值。 Once encrypted, it is XOR'd with the {plain|cipher} text. 加密后,将与{plain | cipher}文本进行XOR。

I've finally got this code working well, and the mistake was very simple. 我终于使这段代码运行良好,并且错误非常简单。 I shouldn't have used decrypt AES function, I should have used encrypt AES function (as noloader had said, and I'd not understood him very well at the first time). 我不应该使用解密AES函数,我应该使用加密AES函数(就像noloader所说的那样,而且我第一次不太了解他)。 Thanks for everybody who helped and here is the fixed code: 感谢所有提供帮助的人,这里是固定代码:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM