2
$\begingroup$

The doc of pycrypto gives an example of using AES in CTR mode:

>>> from Crypto.Cipher import AES
>>> from Crypto.Util import Counter
>>>
>>> pt = b''*1000000
>>> ctr = Counter.new(128)
>>> cipher = AES.new(b''*16, AES.MODE_CTR, counter=ctr)
>>> ct = cipher.encrypt(pt)

I think this isn't safe for encryption of multiple messages with the same key because the counter value defaults to 1. Would it be safe if I do:

iv = os.urandom(16)
ctr = Counter.new(128, initial_value=int.from_bytes(iv, 'big'))

Some articles recommend a timestamp-based nonce (e.g. 64-bit timestamp + 64-bit random value). I was wondering if it's OK to simply draw a 128-bit random value with urandom, and if this implementation is flawless.

$\endgroup$
  • $\begingroup$ Especially with that last comment I think the question is off topic. There are various strategies in the NIST document about CTR (SP 800-38a). Which one is best for you depends on the use case / threat model. How large are the messages for instance, can you keep state, etc. $\endgroup$ – Maarten Bodewes Aug 24 '18 at 3:34
  • $\begingroup$ @MaartenBodewes I read that doc and it gave only 2 examples of initial counter generation in Appendix B. One of them is using a nonce concated with an index. But it doesn't mention how to generate such a nonce. Nothing about timestamp. Nothing about urandom vs random and whether there are pycrypto-specific issues. $\endgroup$ – Cyker Aug 24 '18 at 4:17
2
$\begingroup$

Probably the best thing to do is to decide the maximum message size in bytes, then divide that size by 16 (the block size), call that $m_c$. The number of bytes required to encode $m_c$ is called $l_c$.

Create an IV of 16 bytes and randomize the first (leftmost) bytes, leaving at least $l_c$ bytes at zero. You then have a non-repeating counter of size $l_r$ bytes where $l_r = n - l_c$. That means that you can encrypt about $2^{l_r * 8 - 64}$ messages with the same key while still having a rather small chance of ever repeating the random nonce $r$ and thus the counter.

Time stamps are dangerous, an attacker can try and control the time, clocks can get out of sync, and there may be precision related issues. Time stamps are therefore commonly not used to create nonces - for encryption modes anyway. You don't want to use /dev/random either. Generally /dev/urandom is secure and at least it doesn't block.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Huh? It's a nonce, not a secret. It's CTR mode so the nonces are going to be predictable and that's ok. If this were CBC mode then yeah, it's got to be unpredictable. Context matters :-) $\endgroup$ – Swashbuckler Aug 24 '18 at 19:36
  • $\begingroup$ The question seems to ask for unpredictable nonces and that's perfectly fine. Context does matter indeed; I'll use the one for the question. $\endgroup$ – Maarten Bodewes Aug 25 '18 at 16:51
  • $\begingroup$ @Swashbuckler CTR mode is secure as long as the nonces are never reused - an acceptable approach is to randomly generate them. Otherwise, the state of the counter must be preserved. $\endgroup$ – Iiridayn Feb 4 '19 at 21:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.