[pycrypto] Using Counter for true 64-bit decryption

Dwayne C. Litzenberger dlitz at dlitz.net
Fri Jan 13 11:21:00 EST 2012


On Tue, Dec 13, 2011 at 07:38:12PM +0000, Lance Ware wrote:
>
>Hello,
>
>I am trying to use pycrypto to decrypt a file using AES in CTR mode.  Currently I have a file with a counter value store in the first 16 bytes of the file.  I see in most of the examples the first 8 bytes are stored in the counter value as part of a prefix with the last section starting with zero and incrementing up.  My question is that if I want to have a truly random counter value. Do I need to create my own count class to handle the increment or can i use Crypto.Util.counter class.
>
>I am trying to use the Crypto.Util.counter class but i keep getting errors on CTR: counter returned not 16 bytes.

AES is a 128-bit block cipher.  Therefore, CTR mode needs a 128-bit 
counter.

Typically, one would use a 64-bit block counter prefixed with a 64-bit 
nonce (total: 128 bits).  For example:

     >>> from Crypto import Random
     >>> from Crypto.Util import Counter
     >>>
     >>> nonce = Random.get_random_bytes(8)
     >>> nonce.encode('hex')
     'b474f7e74193327b'
     >>> ctr = Counter.new(64, prefix=nonce)
     >>> ctr
     <_counter.CounterBE object at 0x7f73d1688ef8>
     >>> ctr().encode('hex')
     'b474f7e74193327b0000000000000001'
     >>> ctr().encode('hex')
     'b474f7e74193327b0000000000000002'
     >>> ctr().encode('hex')
     'b474f7e74193327b0000000000000003'

Then, you could do something like this:

     >>> from Crypto.Cipher import AES
     >>> cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
     >>> ciphertext = cipher.encrypt(...)
     >>> ciphertext += cipher.encrypt(...)

There's no good reason to use a "truly random counter value".  AES already 
takes care of scrambling your counter value.  However, if you really wanted 
to do that, you could make you own ctr object (as above) that implements 
__call__, but you'll take a pretty large performance penalty.  
(Crypto.Util.Counter is implemented in C and uses an internal optimization 
that bypasses the normal Python function-call dispatcher.)

Cheers,
- Dwayne

-- 
Dwayne C. Litzenberger <dlitz at dlitz.net>
  OpenPGP: 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7


More information about the pycrypto mailing list