Assuming the following:

  • Key is randomly generated is being used (32 bytes+)
  • IV is also randomly generated
  • Crypto random key generator is used
  • Data being encrypted contains common bytes like { } and " and keys (like JSON)

Which of these modes (CTR, CBC) are more appropriate for storing sensitive information?

Is it possible for someone to discover the CTR counter value knowing some of the bytes in the original message?

Is CBC safer than using CTR for storing data, or would it be more susceptible to a padding oracle?

Is it just a bad idea in general to encrypt a self-describing data structure?

  • 3
    $\begingroup$ Encryption is a general solution and when done right doesn't care about the underlying structure of the data being encrypted. Consider that with CTR, you will need to add authentication yourself (perhaps using an HMAC) whereas OCB already includes that. Have you thought about that? $\endgroup$
    – Thomas
    Apr 12, 2013 at 0:15
  • $\begingroup$ Sorry, for some reason I confused OBC with CBC. $\endgroup$
    – Luke
    Apr 12, 2013 at 14:27

1 Answer 1


As said by Thomas in the comment, modern encryption algorithms should work for all kinds of data, regardless of whether the plaintext is partially known or not.

In both modes of operation (CTR and CBC), for stored data you should remember to get a new initialization vector and reencrypt your whole "message" (or database entry) when changing any part of the data, not try to reencrypt only the changed parts. (Though CBC is likely a bit more robust here – the attacker in the case of IV reuse only gets to see from which block on the data changed, while with CTR mode she can see the XOR difference between the old and new values, assuming she can observe both ciphertext.)

Is it possible for someone to discover the CTR counter value knowing some of the bytes in the original message?

The counter value can be derived from the initialization vector, and thus is considered public knowledge (even if nothing is known about the plaintext). There is no weakness resulting from that, as long as you take care not to repeat your counter values.

With CTR mode, you don't get authentication, which means that an attacker who is able to change your message and observe your programs reactions to that might gain some knowledge about the contents. To avoid this, combine it with a MAC algorithm (preferably on the ciphertext), like a HMAC, which refuses decryption if failed. (Have an independen key for your MAC.)

The same is valid for CBC, just the methods of attacking are different. Here it is even more important to apply the MAC on the ciphertext, not on the plaintext, for the mentioned padding oracles.

As Ricky Dehmer mentioned in a comment, an attack scenario would be someone who got write access to your database, but doesn't have the key, and aims either to maliciously modify the data, or to use chosen-ciphertext attacks to break your encryption privacy.

Don't forget to include the initialization vector in the MAC-ed message.

For an encrypted database column, you could store the tuple (IV, Ciphertext, MAC tag) together, either in one column (most easily in this order) or in three columns, and for decryption pass them together to your decryption function, which should first check the MAC, and then decrypt the ciphertext.

A authenticated encryption mode like OCB or GCM already includes the authentication, so you have less hassle to worry about.

  • $\begingroup$ For some reason I confused OBC with CBC - So I don't have the authentication advantage. But that's interesting about the authentication. If an application is decrypting something from a database, how does HMAC help? Is there a way to add authentication to CBC? That's all I have available in my language (Go), other than CTR. $\endgroup$
    – Luke
    Apr 12, 2013 at 14:36
  • $\begingroup$ HMAC would help if someone was able to change the database but didn't have access to the keys. $\hspace{.3 in}$ Yes, as described in Paulo's answer. $\;\;$ $\endgroup$
    – user991
    Apr 12, 2013 at 16:36
  • $\begingroup$ Go has OpenSSL bindings, does it not? OpenSSL has support for GCM since at least 1.0.1c. $\endgroup$ Apr 12, 2013 at 16:58
  • $\begingroup$ @Luke I added some information about CBC here. $\endgroup$ Apr 12, 2013 at 18:15
  • $\begingroup$ So the safest method for me to use is CBC, with the right care. Is HMAC the safest method for auth, or should I look at something like CMAC (OMAC1)? $\endgroup$
    – Luke
    Apr 12, 2013 at 21:38

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.