1

I want to use CTR mode in DES algorithm in python by using PyCryptodome package. My code presented at the end of this post. However I got this error: "TypeError: Impossible to create a safe nonce for short block sizes". It is worth to mention that, this code work well for AES algorithm but it does not work for DES, DES3 , Blowfish and etc (with 64 block size). To my knowledge CTR mode can be applied in the 64 block cipher algorithms.

from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
data = b'My plain text'
key = get_random_bytes(8)
cipher = DES.new(key, DES.MODE_CTR)
ct_bytes = cipher.encrypt(data)
nonce = cipher.nonce
cipher = DES.new(key, DES.MODE_CTR, nonce=nonce)
pt = cipher.decrypt(ct_bytes)
print("The message was: ", pt)

Thanks alot.

AI_Eng
  • 11
  • 2
  • 1
    CTR mode works technically for 64-bit block ciphers, but the authors of that library consider it insecure. A repeated counter for the same key is a security disaster, and it's too easy to happen with a 64-bit block cipher. – President James K. Polk Oct 14 '18 at 11:59
  • Thanks. I put here a code that work but you are right. – AI_Eng Oct 14 '18 at 12:50

2 Answers2

2

The library defines the nonce as that part of the counter block that is not incremented.

Since the block is only 64 bits long, it is hard to securely define how long that nonce should be, given the danger of wraparound (if you encrypt a lot of blocks) or nonce reuse (if you generate the nonce randomly).

You can instead decide that the nonce is not present, the counter takes the full 64 bits and a random initial value.

iv = get_random_bytes(8)
cipher = DES.new(key, nonce=b'', initial_value=iv)

Finally, I guess that this is only an exercise. DES is a very weak cipher, with a key length of only 56 bits and a block size of only 64 bits. Use AES instead.

0
bs = DES.block_size
plen = bs - len(plaintext) % bs
padding = [plen] * plen
padding = pack('b' * plen, *padding)
key = get_random_bytes(8)
nonce = Random.get_random_bytes(4)
ctr = Counter.new(32, prefix=nonce)
cipher = DES.new(key, DES.MODE_CTR,counter=ctr)
ciphertext = cipher.encrypt(plaintext+padding)
AI_Eng
  • 11
  • 2