My application needs to store some sensitive information. I want to encrypt the data before I store it. At some point in the future, I want to be able to read and decrypt all the data.

For a practical web application, I can pass in a secret key from the ENV, and use it to encrypt and decrypt the data.

What am I supposed to do with the IV though? My reading says you're supposed to generate a new one for each message, but then how would I ever decrypt the data?

  • 1
    In this case should I store the IV along with the encrypted data? security.stackexchange.com/questions/1881/… – Sean Clark Hess Jun 3 '19 at 17:41
  • Yes the first comment on your link answers mine, but I think it would be nice to have an obvious answer on this site. The internet says the IV is public all over the place, but it’s not clear at all how you keep track of it – Sean Clark Hess Jun 3 '19 at 21:41

Standard behavior is just to store and/or transmit the IV along with the ciphertext, often prepended or appended to the data. When decrypting, you read the first (or last) N bytes - where N is the size of your IV - and then decrypt just the rest of the data.

There exist crypto libraries to do this directly, so that you don't even have to worry about the IV; the library generates a suitable one automatically for every new plaintext, attaches it to the returned ciphertext, and accepts the combined IV + ciphertext bundle as input to its decrypt function. If you're at the point of asking a question like this, it would be a good idea for you to try to use a really user-friendly library, such as LibHydrogen, which has a very simple but secure API for symmetric encryption. Note that it covers not only encrypting and decrypting with a random IV (called a "nonce" in the documentation), it also performs authenticated encryption such that an attacker cannot tamper with the ciphertext and leave it in a decryptable state.

  • It should be noted that the IV is public data. With the IV alone you can't do much. And you really shouldn't be using CBC anyways. Use GCM instead. – MechMK1 Jun 4 '19 at 7:46
  • @MechMK1 - can you give me a link on CBC vs GCM? – Sean Clark Hess Jun 4 '19 at 16:15
  • @MechMK1 Both good points. The IV is public data, of no use to an attacker. As for CBC vs GCM, I'd say it's more accurate that the critical thing is to use authenticated encryption in general, than specifically to use a particular authenticated encryption mode (such as GCM). – CBHacking Jun 4 '19 at 17:46

Unless you have a good reason to do otherwise:

  • Use authenticated encryption, for example GCM, CCM, or ChaCha20_Poly1305. Non-authenticated encryption allows some classes of generic attacks: oracle attacks, where the attacker learns information from causing the legitimate party to attempt to decrypt modified ciphertexts.
  • No matter how the underlying library presents the information, treat encryption as providing a single output that contains the nonce/IV, the authenticated-but-not-encrypted data, the encrypted data proper, and the authentication tag. If the library gives you this output in pieces, just concatenate the pieces.
  • For all standard authenticated encryption algorithms, either use a random nonce (and you can let the library generate it randomly), or use a counter (making sure it never repeats). Use the default nonce size unless you really know what you're doing. If you ever have to use CBC or CTR, use a random nonce: these two are badly broken with a simple counter.

All of these rules have exceptions. You'll easily find protocols that violate those rules. There are sometimes good reason to violate these rules, but you have to know what you're doing. The potential attacks are sometimes subtle, but nonetheless devastating.

For example, many communication protocols mandate a specific way to construct the nonce, which both parties follow on their own. This allows saving bandwidth to transmit nonces. That's ok, but only if you know that the way used to construct the nonce is safe, even in the presence of an attacker who sends specially-crafted messages.

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