For each message position or rôle, such as a different time in a conversation or a different field in a database, you must use a distinct nonce, sometimes also called IV.
It doesn't matter what the content of the message is: in your database, you might store the same record content in two different places, in which case if you use the same nonce an adversary can tell that the two places contain the same content. Worse, if you use the same nonce for two different places and two different message contents, an adversary can learn something about both messages or use information about one of them to learn information about another.
Your obligations in the AES-OFB security contract are simple:
- You must pick the key $k$ uniformly at random and keep it secret.
- For each distinct message position that you encrypt with the same key $k$, and each time if you can reuse message positions, you must use a distinct nonce.
Both the sender and recipient must share $k$ and, for each message position, the nonce in that position. You can make the nonce for each message position public and transmit it alongside the ciphertext, or you can make it a function of where the message is, such as a message sequence number in a conversation or a record number in a database. Note that if you ever reuse a message position, e.g. by overwriting a field in a database, then the nonce must also change from the first time you use it to the second time you use it; otherwise an adversary with two snapshots of the database can learn information about the old message and the new message from the two ciphertexts.
In exchange, AES-OFB guarantees that for up to reasonably large volumes of data, an adversary with read-only access to your database won't learn anything about the content of what you have encrypted.
Out of scope:
- an adversary with write access to your database;
- concealing access patterns of your database;
- concealing the lengths of the messages in your database;
If write access might ever be relevant—and it often can be in ways you didn't think of—then you must also use authenticated encryption: for example, AES-GCM, or NaCl crypto_secretbox_xsalsa20poly1305. If you're not sure, err on the side of using authenticated encryption.
If access patterns and message lengths must be concealed, you have to think carefully about how to engineer your application. Beware that compression makes the message lengths a function of the message content, which can cause lengths to reveal information about content!
In the special case where it is safe for an adversary to learn when two distinct message places hold the same message content, you can use a nonce-misuse-resistant authenticated encryption scheme such as AES-SIV or AES-GCM-SIV, which is usually constructed out of a nonce-based authenticated encryption like AES-GCM with the internal nonce chosen to be a pseudorandom function of the message and the caller-specified nonce, at the cost of some performance.
But although the concept has been formalized for some time, nonce-misuse-resistant authenticated encryption schemes are not widespread yet, and the CAESAR competition muddied the waters by not making NMR AEAD a distinct goal from AEAD, and the IETF barged ahead with adopting AES-GCM-SIV, and it's a bit of a mess. Sorry! In any case, it's safer if you can uniquely label all your message positions by a short string of bits (96 bits for AES-GCM, 192 bits for crypto_secretbox_xsalsa20poly1305) and never worry about it again.