[Originally on programmers.stackexchange.com with title: Can you encrypt with AES+CBC and search the encrypted data]
Basically, I'm going to go with Advanced Encryption Standard with either Cipher-Block Chaining mode or Cipher Feedback mode or Output Feedback mode (I haven't decided yet). Each mode requires an initialization vector. The thing is that I want to make the encrypted string "searchable" like this:
Suppose I have a list of database tables together with a "display name" for each table. Conceptually the list would look like this (I've used {xxx} to mean the encrypted form of xxx, and [IVx] to mean an initialization vector):
ENC_DISPLAY_NAME | ENC_TABLE_NAME
------------------------ | -----------------
[IV1]{John's table} | [IV2]{TABLE_3574}
[IV3]{Eric's list} | [IV4]{TABLE_3100}
|
[IV5]{Darren's projects} | [IV6]{TABLE_2823}
[IV7]{Paul's contacts} | [IV8]{TABLE_5843}
Now suppose that I want to allow a search on ENC_DISPLAY_NAME. (Equality searches are all that are needed.) I need to have some way of knowing what initialization vector is used on the display name I want to find.
I think that I should compute a 128-bit hash (maybe a CRC) of the display name, and use that as the IV to compute the encrypted string. That is, if I want to store "Darren's projects", I should do something like this:
AESKey key = ...;
String str = "Darren's projects";
CRCType crc = ComputeCRC(str);
BinaryString enc = crc.ToBinaryString ( ).Concat
(EncryptWithAESandCBC(str, key, (IVType)crc));
INSERT INTO MY_TABLE(ENC_DISPLAY_NAME,ENC_TABLE_NAME) VALUES(enc, ...);
If I want to search for the string instead, do the same steps except the last, and then SELECT * FROM MY_TABLE WHERE ENC_DISPLAY_NAME=enc
.
Has this been tried before? Are there any (security) risks?
[Related question: Compute the AES-encryption key given the plaintext and its ciphertext?]