I'm attempting to learn encryption and have a very basic grasp of it, but I have questions.

First, I'm looking to use AES.

I want to take text, encrypt it with AES using a variable-length key, and return encrypted text. Then I'd like to pass in the encrypted text, the key, and get the original text back. In other words: a Symmetric cipher.

It seems every AES mode that I can see requires a piece of data for decryption that seems problematic to store. For instance, EAX has a nonce that needs stored. CFB has an Initialization Vector (iv) that needs stored.

The way I see it is that I can store the iv in a second location from the encrypted text or I can generate the iv predictably every single time.

Is it considered secure to store the iv or nonce?

  • $\begingroup$ "Is it considered secure to store the iv or nonce such that is accessible by potential attackers?" Yes. According to Kerckhoffs's principle, it is only the key which must be kept secret in a well-designed scheme. $\endgroup$ Jun 7, 2020 at 15:17

1 Answer 1


The way I see it is that I can store the iv in a second location from the encrypted text or I can generate the iv predictably every single time.

Actually, if you don't mind the ciphertext being longer than the plaintext, we can just include the IV/nonce in with the ciphertext. What we typically do is place the IV/nonce at the front of the ciphertext, and place the output of the block mode right behind it. This means that the ciphertext is 8 to 16 bytes longer; for most use cases, we can live with that. We generally also want to store some sort of integrity tag as well (so that if someone modifies the data, we can detect it); that extends the ciphertext a bit more.

Of course, there are some use cases where the ciphertext must be exactly as long as the original plaintext (for example, if we're storing the encrypted data somewhere that was originally intended to store the plaintext, and so the space available to store data is limited to the expected size of the plaintext; this comes up both with encrypted databases and encrypted disk drives). We could, in this case, store the IV/nonce (and the integrity tag) elsewhere, however (in my experience) that's rather rare.

There are specialized modes that are designed to work with the constraint that the ciphertext is exactly the same length as the plaintext, such as XTS (generally used for disk sector encryption) and Format Preserving Encryption modes (designed for encoding small pieces of data, such as a credit card number); unless you require something that needs to live with this constraint, this is typically not the correct solution.

I can generate the iv predictably every single time.

Modes that use IV/nonce are typically badly behaved if you encrypt two plaintexts with the same IV/nonce; with EAX mode, you allow the adversary to deduce the XOR of the two plaintexts; with CFB mode, you allow the adversary to deduce how many blocks the plaintexts agree and on the block they first disagree, the XOR of those two blocks. Hence, generating the IV predictably every single time is generally not the correct solution.

  • 2
    $\begingroup$ SIV and GCM-SIV modes might be worth a mention in the last paragraph. $\endgroup$ Jun 7, 2020 at 3:48
  • $\begingroup$ I took a different approach where I generated the key and IV off of the passphrase using PBKDF2 with an unspecified number of iterations (>100,000 though). Obviously, it's nowhere near usable at this stage, but I think I like your approach, as well. With that, I can concatenate the hash, the salt, the iv, and the ciphertext all into one blob for storage. If not for this purpose, what is PBKDF2 useful for, then? $\endgroup$ Jun 9, 2020 at 13:29
  • $\begingroup$ @UtahJarhead: while I'm not excited about converting a password into a key, I recognize that sometimes that's what your situation is constrained to. That said, the salt is critical; you really need to make sure the salt is long enough that it effectively never repeats (and don't forget to include the salt in your PBKDF2). On the other hand, the IV is used to make sure that two different encryptions with the same key doesn't leak anything; if you never reuse a key, it's not that critical. On other hand, if it's cheap to include it, there's no other reason to not use a random IV. $\endgroup$
    – poncho
    Jun 9, 2020 at 14:18
  • $\begingroup$ @UtahJarhead: also, when you say "hash", do you mean the integrity tag (the MAC of the ciphertext, or the AEAD integrity tag)? Just including the hash of the message doesn't help (an adversary can compute hashes themselves). Also, if you do use a MAC, you need to make sure that you MAC everything that's relevant (IV, salt, we generally toss in everything in the ciphertext other than the MAC itself); that's one nice thing about AEAD; someone else has thought it through, and so we don't have to worry if we forgot something.. $\endgroup$
    – poncho
    Jun 9, 2020 at 14:24
  • 1
    $\begingroup$ @UtahJarhead: the MAC (Message Authentication Code) or AEAD integrity tag is there to validate that the ciphertext that the decryptor reads is exactly the same as the ciphertext the encryptor generated. That is, if we assume an adversary who can modify the stored ciphertext, well, he can always prevent us from decrypting it (by replacing the ciphertext with random gibberish); what those try to do is ensure they can't gain any further advantage; that any change the adversary makes causes a decryption error (and hence we know something got changed) $\endgroup$
    – poncho
    Jun 12, 2020 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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