9
$\begingroup$

I'm interested in developing software capable of encrypting personal files (which will ultimately be backed up to the cloud) and have been doing my best to follow best practices.

There are many forms of authenticated encryption. (AES-GCM, AES-SIV, AES-GCM-SIV, CBC + HMAC, CTR + HMAC, etc.) However, I'm having a hard time determining which of these modes-of-operation suits my use-case best. Speaking broadly:

I've heard many times that "GCM is harder to get right" due to the serious risks associated with nonce reuse as well as its predisposition to side-channel attacks if implemented poorly. Although it is fast.

I know AES-SIV is at least utilized by Cryptomator, a tool similar to what I'm trying to develop, (per their architecture docs). AES-SIV has a smaller penalty for nonce reuse compared to GCM but perhaps isn't as fast.

AES-GCM-SIV attempts to combine the positives of both GCM and SIV by being both fast and somewhat resistant to nonce reuse.

As far as CBC + HMAC is concerned, HMAC leverages 256-bit authentication tags over GHASH's weaker 128-bit authentication tags (used by GCM). However, CBC cannot be parallelized in the same way GCM can.

CTR + HMAC can be parallelized in a way similar to GCM but with stronger authentication tags. (Again, HMAC using 256-bit authentication tags over GHASH's 128-bit authentication tags)

Despite the reading I've done so far, I haven't been able to determine why one might choose one of these methods over the other. At the end of the day, I would really just like to secure my files safely in the cloud with at least some assurance that the files I encrypt are authentic and have not been tampered with or corrupted in any way.

I would really appreciate any help that could point me in the right direction.

$\endgroup$
10
  • $\begingroup$ I would do ctr+hmac(blake2) for backup $\endgroup$ Commented Jan 4, 2020 at 8:20
  • 3
    $\begingroup$ @RichieFrame Why CTR and HMAC-BLAKE2 instead of, say, ChaCha20-Poly1305? $\endgroup$
    – forest
    Commented Jan 4, 2020 at 9:03
  • 1
    $\begingroup$ @meci: Based on GCM is harder to get right I suppose you are going to implement by yourself one of these algorithms. I would discourage you from doing that. Or you are going to use some library and you are not sure if the authors have implemented it correctly? $\endgroup$
    – mentallurg
    Commented Jan 4, 2020 at 13:46
  • 1
    $\begingroup$ Well, maybe it is possible to build a table with e.g. relative speed, maximum amount of bytes, flexibility, robustness etc. for all these modes. Might be quite a bit of work though, you often see these kind of comparisons in papers by academics that cannot come up with anything more original. $\endgroup$
    – Maarten Bodewes
    Commented Jan 4, 2020 at 20:29
  • 1
    $\begingroup$ Evaluate the risks in your specific case. Then may be you come to conclusion that even AES-GCM without any HMAC is quite sufficient for your case. Then you will have multiple candidates. I find that actually all you listed are fine for your case. Now think of other criteria like platform (Java, C#, C++, ...), available libraries, community and level of support, bug fixing practices in that community, complexity of the API (for you as a new user), performance of the code. $\endgroup$
    – mentallurg
    Commented Jan 5, 2020 at 16:04

2 Answers 2

5
$\begingroup$

I went through this decision process in 2018 and ended up going with something very conservative: encrypt-then-MAC with AES-256-CBC and HMAC-SHA-512 truncated to 256 bits.

This was fast enough for my use cases, but is much slower than many of the alternatives. The AES part is fast on Intel processors; hashing ends up taking ~80% of the time on long messages.

Alternatives worth considering today:

Replace HMAC-SHA-512 with keyed BLAKE3 (~2.5x faster for long messages). BLAKE3 itself is very new, but has a somewhat mature lineage.

XChaCha20-Poly1305 (~2x faster for long messages). Nonces can be up to 192 bits, so there's less of a risk of collisions.

AES-GCM-SIV (~5x faster for long messages). Doesn't seem to be widely implemented yet.

Note: These performance estimates are vaguely based on a "typical" 2016 x86-64 processor, which has dedicated AES instructions and some general-purpose SIMD, e.g. AVX.

$\endgroup$
2
$\begingroup$

In cryptographic operation modes that require the initialization vector to be non-repeated rather than random, the initialization vector is called "nonce" (number used once).

Do not design the implementation of a mode if you cannot fulfill the requirements of the mode. For example, if a mode depends on a uniqueness of the initialization vector, you have to do all your best to ensure the uniqueness. If you cannot guarantee the uniqueness, choose another mode that does not have such a requirement. Otherwise, you may have false sense of security and your application may eventually end up in being used in such a scenario that ignorance of the basic requirement will lead to failure. There are many examples when cutting the corners ultimately lead to failure. For example even occasional use of the same one-time pads by different senders in the 1940s allowed the adversary to decrypt the messages. Although it has been known that such reuse is a serious weakness, people probably thought that cutting the corners would not have consequences, but it had.

So, rather than trying to find the modes that are "somewhat resistant to nonce reuse", ensure that your implementation does all its best to prevent nonce reuse, or find another mode that does not depend on nonce. The problem of ensuring the uniqueness of the nonce is a matter of a separate discussion, but it is practically achievable even in your scenario. Since your scenario does not allow timing attacks or padding oracle attacks, you may use AES-CBC with any MAC, like two-pass HMAC with SHA-2 or one-pass HMAC with SHA-3 in any order, like Encrypt-then-MAC (EtM), Encrypt-and-MAC (E&M), MAC-then-Encrypt (MtE). if you don’t need higher speed and parallelism. Otherwise, use AES-GCM AEAD. However, since the CBC mode give you many options with HMAC, I would have followed the KISS (keep it simple) principle, to be less inventive, and have just implemented the AES-GCM AEAD.

$\endgroup$

Your Answer

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

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