Tinkering with pyDes mode of operation

434 Views Asked by At

So, in pyDes, a cryptographic library of DES, there is an API, which goes like this pyDes.des(key, [mode], [IV], [pad], [padmode]). An usage of it goes like this k = des("DESCRYPT", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - where I can either use CBC or ECB mode of encryption.However, as an assignment from my professor, I am told to encrypt using pyDes library, but using CBC and Counter Mode manually.

I managed to do CBC mode fine, unfortunately I am stuck with the counter mode. Using the given api of des(key, CBC, IV ...) I can only use IV when I use CBC or ECB mode of operation. I can not use it something like des("hello", mode = None, "foo",....) where "foo" is my IV.( I am supposed to implement Counter mode of operation and the iv is random in every single iteration) So, my question is did anyone faced this issue, and tried to overcome it.

1

There are 1 best solutions below

0
On

The main operation that you need to isolate in order to implement some mode is the actual block cipher without a mode of operation or padding. pyDes doesn't seem to provide direct access to the block cipher directly, but you can emulate it easily with the ECB mode. ECB is a simple execution of the block cipher on all input blocks in the same way.

The idea would be to create a counter input stream, execute ECB on the input stream to get the key stream and then XOR every byte of the plaintext with the corresponding byte in the key stream.

Steps for CTR mode:

  1. Generate a random nonce (IV) in the range of 0 to 1<<64 (DES block size) which is the starting counter:

    import random
    r = random.SystemRandom()
    nonce = r.randrange(0, 1<<64)
    
  2. Convert the counter for each block of the plaintext to bytes with struct.pack('>Q', counter) and increase the counter by one

  3. Repeat until you have at least as much bytes in the counter stream as in the plaintext
  4. Encrypt the counter input stream with ECB mode and any available padding
  5. XOR the key stream and the plaintext and throw away the rest of the key stream (if any)

Since CTR mode is a stream cipher, you can use the exact same operation for decrypting with the only difference that the nonce must be supplied from outside. You can prepend the nonce to the ciphertext so that it can be used for decryption. It doesn't have to be secret, but it needs to be unique if the same key is used.

Note that the block size of DES and 3DES doesn't permit to encrypt many ciphertexts or long ciphertexts with CTR under the same key. If you do then you need to change to a block cipher with a bigger block size like AES.