I came across some code in our project that encrypts usernames (limited to 50 chars, most are less than 10) using the following parameters:

IV size is 16 bytes

Key size is 32 bytes

Algorithm is CBC-AES (256bits)

Is there a security issue because of these parameters? Why would you use CBC and not ECB with a key size larger than 50 chars? Is it dangerous to use an IV smaller than the key size? What is the proper way to encrypt usernames in a database?

EDIT:
The IV is being reused for every username. This is not good apparently. I can write a migration script and change the algorithm etc, as long as the usernames are encrypted in the end. If anyone has any suggestions on how to best do this securely that would be very helpful.

What is the threat model? Specifically, what kinds of attacks are you trying to protect against? Usernames are generally considered to be public information.
–
Stephen TousetFeb 14 '13 at 3:35

How are you storing the key? Can you guarantee that an attacker who compromises the server will not be able to steal the key? If not, encryption won't do you much good! (In contrast, salting and hashing passwords is a good practice, because there's no key sitting around that can undo these operations).
–
SethFeb 14 '13 at 6:01

1

The idea is to protect the privacy of usernames (which are actually real names) against attacks on the web application (SQL injections leading to leaking of usernames). The encrypted usernames themselves are stored in the database, the key and IV are in the web application. I know this is ridiculous, but I'm interested in trying to fix this as much as possible while not going against the ridiculous design requirements.
–
amaterasuFeb 14 '13 at 6:22

AES has (in all variants) an 128-bit block size, which means that CBC needs an 128-bit (=16 bytes) IV. So no issue here (apart from reusing it, which totally destroys the effect of having an IV at all).
–
Paŭlo Ebermann♦Feb 14 '13 at 9:19

1 Answer
1

the objective is to protect the confidentiality of the user names from an attacker having read access to the encrypted data, the ability to add usernames of her choice, and nothing else (in particular, no access to the key, even by proxy of a computer or device holding the key, or side channel);

the IV is randomly chosen for each individual username encrypted (or re-encrypted after an edit);

the key has been randomly chosen, is not compromised, and is used only for that usage;

then the system using CBC is safe, as far as we know (this follows from IND-CPA security of AES-256 in CBC mode). Notice this is highly theoretical. If an adversary can get remote access to a PC, and unless an HSM or Smart Card is used to hold the key, you have no strong argument that the key did not leak. Even if you use such tamper-resistant hardware to store the key, you have no argument that the adversary could not use that hardware, or otherwise access the plaintext.

Using ECB, the system would be unsafe even with the theoretical hypothesis given. In particular, it would be easy, from the ciphertext, to spot:

identical usernames:

usernames identical up to the first 16 characters bytes;

with high confidence, if a username uses more or less than 16 characters bytes (which in turn could be correlated with ethnic origin).

Update: Having the same IV for every user is a classical mistake, and brings back some (but not all) of the weaknesses of ECB. In particular, it is trivial to spot identical usernames; and thus to spot if a given username is present, for an attacker able to add a user with a given username. Depending on the number of usernames an adversary can realistically add, and on the encoding used for user names (which has considerable influence on the difficulty to exactly guess a 16-byte fragment of a username), it would be more or less easy to recover a fraction (or perhaps all) of the usernames.

IMHO, simply put, there is no proper way to encrypt usernames in an online database. Problem is, whoever can use the database to get the usernames will circumvent any crypto there might be; this is not a cryptographic problem. If you only want to give the illusion of security (or, equivalently, do the best you can in an implementation running in a nondescript environment), use CBC or CTR encryption with a random IV for each encryption of a record.

They key and IV are hardcoded and used for every username. An attacker is able to register new usernames and see the ciphertext of them if he has access to the SQL db.
–
amaterasuFeb 14 '13 at 6:26

@amaterasu When you say the "key an IV are hardcoded and used for every username" do you mean that only one IV is being used? Each username must have its own IV, and in CBC mode, each IV needs to be a random 16-byte value. It's fine if the attacker sees the IVs, so you can go ahead and store them in the database.
–
SethFeb 14 '13 at 6:30

2

@amaterasu: AES-256 uses 16-byte, not 32-byte blocks (only the key is 32-byte); and, depending on encoding, that might be good for 16, 8, more or even less characters. If the IV is global, indeed CBC and ECB are equally insecure when all names fit in a block, and CBC is marginally less insecure above that threshold.
–
fgrieuFeb 14 '13 at 7:50

1

Encrypting part of the database does protect against some attacks: SQL injection (if the key isn't in the database and the injection cannot be escalated), leak of plaintext backups.
–
GillesFeb 14 '13 at 10:20

1

@Gilles: Yes, proper encryption of part of a database protects against adversaries which only manage to get access to the encrypted version of the database; thus is not useless. Problem is, if general security measures can't prevent an access that no user should have, why would they better prevent against regular access to the deciphered data (which some users must have), or access to the key, or to the device/process that can decipher using the key?
–
fgrieuFeb 14 '13 at 12:01