PyCrypto problem using AES+CTR

后端 未结 5 1209
轮回少年
轮回少年 2020-12-03 14:37

I\'m writing a piece of code to encrypt a text using symmetric encryption. But it\'s not coming back with the right result...

from Crypto.Cipher import AES
i         


        
5条回答
  •  北海茫月
    2020-12-03 15:39

    I may be definitely late and I may have overlooked the previous answers, but I didn't find a clear statement of how this should (at least IMHO) be done according with the PyCrypto packages.

    The Crypto.Util.Counter package provides callable stateful counters, which are very useful, but it was easy at least for me to use them improperly.

    You have to create a counter, with e.g. ctr = Counter.new('parameters here'). Every time your counter is called by your counter mode cipher object to encrypt the message, it is incremented. This is needed for good cryptography practices, otherwise information about equal blocks may leak from the ciphertext.

    Now you cannot call the decryption function on the same cipher object, because it would call again the same counter which in the meanwhile has been incremented, possibly several times. What you need to do is to create a new cipher object with a different counter initialized with the same parameters. In this way the decryption works properly, starting the counter from the same point as the encryption was done.

    Working example below:

    # Import modules
    from Crypto.Cipher import AES
    from Crypto import Random
    from Crypto.Util import Counter
    
    
    # Pad for short keys
    pad = '# constant pad for short keys ##'
    
    # Generate a random initialization vector, to be used by both encryptor and decryptor
    # This may be sent in clear in a real communication
    
    random_generator = Random.new()
    IV = random_generator.read(8)
    
    
    # Encryption steps
    
    # Ask user for input and pad or truncate to a 32 bytes (256 bits) key
    prompt = 'Input your key. It will padded or truncated at 32 bytes (256 bits).\n-: '
    user_keye = raw_input(prompt)
    keye = (user_keye + pad)[:32]
    
    # Create counter for encryptor
    ctr_e = Counter.new(64, prefix=IV)
    
    # Create encryptor, ask for plaintext to encrypt, then encrypt and print ciphertext
    encryptor = AES.new(keye, AES.MODE_CTR, counter=ctr_e)
    plaintext = raw_input('Enter message to cipher: ')
    ciphertext = encryptor.encrypt(plaintext)
    print ciphertext
    print
    
    
    # Decryption steps
    
    # Ask user for key: it must be equal to that used for encryption
    prompt = 'Input your key. It will padded or truncated at 32 bytes (256 bits).\n-: '
    user_keyd = raw_input(prompt)
    keyd = (user_keyd + pad)[:32]
    
    # Create counter for decryptor: it is equal to the encryptor, but restarts from the beginning
    
    ctr_d = Counter.new(64, prefix=IV)
    
    # Create decryptor, then decrypt and print decoded text
    decryptor = AES.new(keyd, AES.MODE_CTR, counter=ctr_d)
    decoded_text = decryptor.decrypt(ciphertext)
    print decoded_text
    

提交回复
热议问题