encryptioncryptographyaesrijndaelblock-cipher

AES CTR without IV - same key for multiple messages - safe?


I want to make a web page in js that will encrypt plaintext, so I can send it to friend, who will use the same web page to decrypt it.

We will share the same secret key and use it for multiple messages.

I know that when using AES CBC- there needs to be random iv for every message, but Id like to use AES CTR.

I will use 256 key, not password.

I have 2 questions:

  1. Can I use the same password multiple times with CTR and no iv ?
  2. If I will use CBC is it safe to send iv in plaintext along with encrypted message?

I'm using aes-js and basic common modes of operation:

https://github.com/ricmoo/aes-js#ctr---counter-recommended

https://github.com/ricmoo/aes-js#cbc---cipher-block-chaining-recommended

I want best possible security.


Solution

  • First, there is no such thing as CTR or CBC with "no IV." You are likely just using all zeros as the IV. There is always an IV. (CTR calls its IV a nonce.)

    CTR must never, ever reuse an nonce+Key pair. It can completely destroy the encryption. This is a major reason to avoid CTR unless you know what you're doing. It is difficult to use correctly and has horrible failure modes. (The fact that WEP is now considered completely broken is very closely related to this question.) I'm not saying that CTR is bad when used correctly; I'm saying that small errors are catastrophic.

    CBC should never reuse an IV+Key, but it is not as devastating. This is a major reason that CBC is a very good choice for non-experts. Even when used incorrectly, it is relatively secure. Reusing the IV+Key pair, however, introduces two major problems:

    The standard construction, well suited to non-experts because the tools are readily available on many platforms and relatively easy to use correctly, is as follows:

    Random IV + CBC-ciphertext + HMAC
    

    The IV is not secret. It is standard and correct to send it along with the message. The IV must only be unpredictable by attackers. Even an occasional reuse leaks little information, as long as attackers cannot predict (or control) the IV. Obviously if it's always zero, predicting it is trivial.

    CBC (and also CTR) does not provide any authentication of the message. It may be modified in transit. If an attacker knows the plaintext message, there are cases where they can modify the encrypted message in order to decrypt in a known way. For example, if I know (or can guess) the message reads "To Bob: $100" it is possible to modify that message without knowing the password to be "To Eve: $100". Authentication prevents this. The way to authenticate CBC is with an HMAC (encrypt first, then hash).

    For an example of this format in practice, see the RNCryptor format, including RNCryptor-js.

    Maarten mentions GCM, and I agree that it is an excellent piece of cryptography, but I disagree that non-experts should use it. As a counter-mode, it has the same dangers as CTR. If used incorrectly, it completely falls apart (vs CBC which has a much smoother loss of security). This is a highly opinionated subject, however, and GCM fans are not wrong. I just disagree on what "standard best practice for non-experts" should be.

    To "I want best possible security," then you absolutely need to involve security experts. Selecting the right block mode is the simplest part of securing a system, and there are many other pitfalls that are just as important.