2
$\begingroup$

I implemented AES128-CBC algorithm and what I need is to be able to compare encrypted text without decrypting.
Is the only way to use static or no iv to achieve this?
. Any ideas?

Use in code -Something like :

select x from ins left join Users ui on ui.UserIDNumber=id

or Select * from users where userIdNumber = @userIdInput .
We encrypt the data in Angular

Use Case
User can type the field, we do a search and return him the matching records. Or he just asks for all the records and we return the records with the value still encrypted.
There's a button he can click if he wants to have the fields decrypted.

$\endgroup$
5
  • 1
    $\begingroup$ I think, it will be better to display the column structures and required query in a minimalist way that represent your problem. $\endgroup$
    – kelalaka
    Sep 18 at 18:12
  • 1
    $\begingroup$ There is still lots of missing information for proper answer like what are the mode of operations are used on the column that needs to be join or the field that need to be query. Remember, for deterministic query, CryptDB used ECB mode. $\endgroup$
    – kelalaka
    Sep 18 at 18:20
  • $\begingroup$ I don't say anything to use now. I'm trying to understand the the problem and missing parts. You said the db there's an encrypted field which also needs to do join with another encrypted field in another table. so what can you do and not depending on the encryption modes on the this and the query column. $\endgroup$
    – kelalaka
    Sep 18 at 18:31
  • $\begingroup$ Read my first comment. Describe your problem in complete detail in minimalist way. Update your question in proper way. Take your time, you know your problem's details and that is important. $\endgroup$
    – kelalaka
    Sep 19 at 8:35
  • $\begingroup$ Does each column uses the same key and IV? What about the rows? Where does this DB is located? $\endgroup$
    – kelalaka
    Sep 19 at 12:48

3 Answers 3

6
$\begingroup$

Don't use the same IV twice with CBC. The ciphertext reveals when two plaintexts start with the same 16-byte block. This makes it significantly easier to brute-force partially-known plaintexts to find them in your database, as well as to obtain partial information about records (e.g. with a plausible format, it might make it easy to find people with the same name).

In fact, you should not use CBC at all. CBC is an obsolete mode that is available in a lot of libraries and mentioned in a lot of documentation because it used to be a de facto standard. But since the 1990s our knowledge of block cipher modes has improved and we know that while CBC isn't broken, it's very tricky to use correctly. There are subtle attacks when two messages are encrypted with the same key and related, but distinct IVs. There are also subtle attacks when the IV is related to the ciphertext.

What you're looking for is called deterministic encryption. Normally, encryption is randomized or pseudo-randomized, so that if you encrypt the same message twice, an adversary can't tell that it's the same message by looking at the plaintext. Encryption modes achieve this by randomizing the IV, or at least ensuring that the same IV is not reused for the same message with the same key.

There's a trick to making deterministic encryption out of normal encryption: calculate the IV from the plaintext. If the IV only depends on the plaintext, then encrypting the same plaintext twice results in the same ciphertext.

There are modes called “synthetic IV” modes that use an IV which is partly a nonce (i.e. never reused with the same key) and partly derived from the message. If you feed a constant input as the nonce, you get deterministic encryption. Two popular choices are AES-SIV and AES-GCM-SIV.

If you're stuck with antique crypto libraries (the Javascript ecosystem is unfortunately not very good when it comes to crypto), you can still use CBC, but you need to be careful. To calculate an IV from the plaintext, use SHA-256, which is commonly available and fast. But don't just take SHA-256(plaintext): the IV needs to be stored in the database (otherwise you can't decrypt), so the IV calculation must involve a secret key. You can use the first 128-bits of SHA-256(K1 + plaintext), where K1 is a (at least) 128-bit secret key. Use a different key from the AES encryption key because it's bad hygiene to use the same key for the same purpose, although it doesn't actually matter in practice because SHA-256 and AES are completely unrelated.

$\endgroup$
1
  • $\begingroup$ @FSDev If you use AES-SIV, it already does the work of deriving the IV from the plaintext, so just pass it your plaintext and no nonce. $\endgroup$ Sep 20 at 9:06
4
$\begingroup$

I implemented AES128-CBC algorithm and what I need is to be able to compare encrypted text without decrypting. Is the only way to use static or no iv to achieve this?

I believe that the core problem is "how do I encrypt data in such a way that I can find matching plaintexts with minimal processing?"

Well, the easiest way I can think of is deterministic encryption. That is, whenever you encrypt a specific text, you always encrypt it into the exact same ciphertext. This makes finding matching plaintexts easy (you just look for matching ciphertexts).

Now, using the same IV whenever you encrypt would do this; however this has an issue. With CBC mode, that would also leak when two different plaintexts have the same first 16 bytes (even if they differ afterwards); this may be leaking more than what you'd desire. On the other hand, if the field length is always 16 bytes or less, this does work.

Assuming that the field can be longer than 16 bytes, well, since you have implemented CBC mode anyways, the easiest thing to do is use an IV which is a function of the plaintext (and hence encrypting the same plaintext twice would use the same IV). If you compute the CBC-MAC (which is essentially "perform a CBC mode encryption with a fixed IV, except you tweak the last plaintext block and discard everything except the last ciphertext block - that last ciphertext block is the result of the CBC-MAC computation), you can use that as the IV for the normal CBC mode encryption. In addition, when decrypting, when you get the plaintext, you can recompute the CBC-MAC of the plaintext you get and compare that with the IV - that gives you some integrity protection (the attacker can replace one field entry with another - we can't prevent that if we use deterministic encryption).

$\endgroup$
5
  • $\begingroup$ The trick about generating IV from plaintext is a nice solution. I would like to note that there are tons of integrity, authentication, and even roll-back countermeasure on the academy, though never heard that they are used much, the last sentence is a bit off the point due to English ( of my own perhaps), this (idea) can't prevent that is better. $\endgroup$
    – kelalaka
    Sep 19 at 18:29
  • $\begingroup$ @kelalaka: what I meant was "if you always encrypt (say) Alice ->5fd79nkg, then the attacker can place 5fd79nkg into any field encrypted with the same key, and Alice will be there". Now, there are other ideas that use nondeterministic encryption (and a tag which allows matching fields to be obvious); you can avoid this 'rewriting with another valid entry' attack (but it does make the search for matching fields slightly more expensive) $\endgroup$
    – poncho
    Sep 19 at 18:38
  • $\begingroup$ Do you have a source for recommending the use of the CBC-MAC output as an IV? Rolling your own crypto is a bad idea in general, and fiddling with the IV, with feedback from the output of CBC to its input, seems like a recipe for disaster. You should use a standard SIV mode instead, or, if you really have to DIY because of poor libraries, at least use something like SHA256/128(prefix+message) as the IV. $\endgroup$ Sep 19 at 19:36
  • $\begingroup$ @Gilles'SO-stopbeingevil': actually, if you go through the CBC-MAC processing, it is essentially the same as CBC (with the extra secret block being xor'ed in at one point - that can't harm anything). Hence, if there is a weakness in this construction, there is a weakness in the standard CBC construction, and we know there isn't. $\endgroup$
    – poncho
    Sep 19 at 21:30
  • $\begingroup$ @poncho The CBC MAC is a CBC ciphertext block. CBC constructs more ciphertext blocks by xoring a ciphertext block with the plaintext. The IV gets xored with a plaintext block — exactly the same thing. I'm worried about a scenario where the same two blocks end up being xored in different contexts. This might not be a weakness in the standard construction because that assumes random IVs, or it might be a weakness in the standard construction because that is vulnerable to chosen-ciphertext attacks (e.g. famously, padding oracle). $\endgroup$ Sep 20 at 8:20
1
$\begingroup$

First of all, you need the same encryption key and the IV that were used during encryption to decrypt your data. I guess each field has its own key and IV. If you want to compare arbitrary string m (in plaintext) with encrypted data e, you can always compute x = Enc(m, key, IV) and compare x == e.

If only user has access to keys and IVs, then you have to script search button to send encrypted input.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.