# Encrypting decimal values with AES

I have a column in a database table called "Amount" that will store decimal values encrypted with AES. It's highly likely that the same amount will exist in multiple rows in the table and be encrypted with the same key. Furthermore, most of the plaintext values that will be encrypted are <5000. Are there any specific factors I need to consider or be aware of that might affect security in this sort of scenario vs a scenario where I'm storing some other data type such as strings with unique and unpredictable values? More specifically, I'm wondering if this scenario is vulnerable to known plaintext attacks.

• Bytes are bytes. Just use AES in GCM mode, and always use a unique IV every time you encrypt with that key. – Stephen Touset Jan 28 '17 at 6:02

You don't normally encrypt anything with just AES. AES is a block cipher, and needs to be used with an appropriate mode of operation in order to securely encrypt general data.

In general terms, there are two kinds of modes of operation: traditional ones, such as CBC, CFB, OFB and CTR, which only protect the data against passive attacks by eavesdropping adversaries, and authenticated modes which also protect the data against active tampering. While a traditional mode of operation may be sufficient for your particular needs, my advice would be to always use an authenticated mode such as AES-SIV if at all possible. It's safer, and has no real down sides.

In any case, as long as you use AES with a secure mode of operation, with a random and/or unique IV/nonce as required by the mode, and respecting any other relevant constraints such as the maximum number of plaintexts encrypted with a single AES key (e.g. up to $2^{48}$ plaintexts for AES-SIV), and take care to keep the AES key secret, then you're safe from any known-plaintext (or, for authenticated modes, even chosen-plaintext) attacks. For details, consult the definition and any relevant standards documents for your chosen mode of operation (such as RFC 5297 for AES-SIV).

Ps. Many lists of block cipher modes of operation, such as the Wikipedia page I linked to above, also include "ECB mode". This mode exists to provide direct access to the underlying block cipher, and generally should not be used except to implement other modes of operation (or MACs or other similar block cipher based cryptographic algorithms). In particular, it is not generally secure against known-plaintext attacks.

In your particular use case, where all the messages to be encrypted consist of small numbers, one can define various custom schemes that can provide known-plaintext and even chosen-plaintext attack resistance without using a conventional mode of operation (and thus possibly avoiding the slight storage overhead they require).

For example, you could encode your numbers as 64-bit integers, combine each integer with a unique 32-bit nonce value (ideally, a unique ID for the database row the number belongs to) and a fixed 32-bit check string (e.g. all zeros), and encrypt the resulting 128-bit block with the raw AES block cipher (i.e. "ECB mode"). This would produce a 128-bit ciphertext which is guaranteed to be unique (as long as all your nonces are distinct), which is tied to the database row it belongs to (via the nonce), so that moving an encrypted value from one row to another can always be detected as a forgery, and which is fairly resistant to forgery attacks even if the nonce cannot be checked (since a forged ciphertext has only a $1/2^{32}$ chance of decrypting to something with the correct check value).

However, while such a scheme should indeed be secure, I would generally not recommend it, since it isn't standardized (and thus requires extra implementation effort and extra security review) and lacks the flexibility of standard modes of operation.

In particular, using AES-SIV (with the row ID as the nonce) achieves a comparable security level, requires less than twice as much storage space (128 + $d$ bits, where $d$ is the size of the field being encrypted), and allows you to also link the ciphertext with arbitrary associated data (e.g. column name, timestamp, transaction ID and/or any other relevant unencrypted metadata) and to use the same method for encrypting other data of arbitrary type and size. It's also a standard construction provided by many crypto libraries, and hopefully familiar to anyone reviewing your design.

• Encrypting and authenticating parts of a database with an authenticated cipher (and keeping its key safe) is not enough to protect the database from tampering. For example, it is still possible to (a) exchange authenticated fields, or (b) roll back a field to a previous state. Adding the location to the authenticated prevents (a), but (b) is harder to prevent. – fgrieu Jan 28 '17 at 19:01