Hacking a CTF: Do not use ECB mode for encryption
znano.eu.org
znano.eu.org
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
AES-256-GCM 655193.56k 1747223.44k 3399072.36k 4490100.61k 5033129.30k 5108596.96k
AES-256-OCB 631357.15k 2268916.74k 4794610.30k 6492985.36k 7174274.14k 7301540.60k
AES-256-ECB 997960.96k 3972424.35k 8096120.70k 8105542.89k 8179659.94k 8188882.64k
[1] <https://en.wikipedia.org/wiki/OCB_mode>, <https://competitions.cr.yp.to/round3/ocbv11.pdf>The reality is that this was a lot more relevant 10 years ago; today, new code is much more likely to use GCM or Chapoly than to generically compose a cipher mode with (hopefully) an authenticator.
Sounds more like a foot gun to me.
If you meant using a counter-based cipher: it is. GCM is the most popular mode on the modern internet, for example.
If you meant using multiple ciphers: because it adds overhead without adding security.
But you're right, the important takeaway here is that encrypting with a weak and a strong cipher sequentially may be less secure than just using the strong cipher. For those to which this seems counterintuitive, here is the paper that shows this result: https://link.springer.com/article/10.1007/BF02620231
And I thought xoring them forces attackers to have to break all of the ciphers instead of just one. That seems pretty useful.
If you hashed the ciphertext then anyone can re-hash a modified version.
What you're looking for is a HMAC, which works, but it's usually slower than a block mode that integrates authentication functionality (like OCB, or GCM).
It's true that you'd have to break all the ciphers, but we're generally very confident about the security of our symmetric ciphers, so unless you're very paranoid it's just a waste of clock cycles,
I don't buy the confidence thing but sure.
https://cryptopals.com/sets/4/challenges/26
You could CTR-encrypt a message, and then use a hash function in an HMAC construction. HMAC takes a secret key, so an attacker can't compute the HMAC of some other message and swap it in. CTR+HMAC is pretty common, though it's a design smell in a modern system, virtually all of which use AEADs rather than hand-rolled ("generic composition") systems.
Encrypt() is CTR, so you can flip bits in ciphertext to alter the same bits in the plaintext.
You know the plaintext and the hash and you know where the hash is, so you can mechanically rewrite the hash to be whatever you need it to be.
You can prove this to yourself in Python or Ruby or whatever: just CTR-encrypt "We all live in a yellow submarine", along with its hash. Then bitflip "yellow" to "orange", compute the hash for "We all live in a orange submarine" (ignore the grammar), and bitflip that into the original hash.
There are formalisms to why hash-then-encrypt is unsafe that I'm not giving you here, because I'm not smart enough to pull them out of the top of my head, but the scenario I just described is already a game-over vulnerability in many settings; a similar fact pattern has broken lots of encrypted cookie schemes, which you do in fact know the plaintext, and some bit of the plaintext (like "admin=n") happens to be incovenient to attackers.
I actually was imagining the key would be used in the hash function (just like it's also used by the encryption function). It didn't occur to me to explicitly mention it, but I see why it can be interpreted differently otherwise. (Thanks for explaining/clarifying.)
If I did that though, wouldn't that take care of this?
Most people in your situation would just use HMAC. You're not really optimizing anything by avoiding HMAC, but if you try to roll KMAC-SHA2, you've created a cryptographic vulnerability.
Flawed as in "cryptographically insecure". Which in this case is "it lets you predict something about the hash of one input from the hash of a different input".
As I see it, a cryptographically secure (read: flawless) hash function is just another name for an RNG whose output is computationally impossible to predict without knowledge of its seed. Hash functions that are vulnerable to length extension don't satisfy that: their outputs on longer inputs can be predicted from their outputs on shorter inputs, without any knowledge of their keys. That's a pretty big flaw. To me they're similar to hashes that lack the avalanche effect. They're not cryptographically secure as far as I'm concerned.
> you need a MAC, not a "hash"
I hate jargon honestly. I just refer to these (cryptographically secure) hashes and move on with my day. To me a hash that's vulnerable to length extension isn't cryptographically secure. I kind of assume people understand I'm assuming sufficiently strong building blocks when proposing a way to compose them, otherwise it makes for an uninteresting discussion.
> Most people in your situation would just use HMAC. You're not really optimizing anything by avoiding HMAC
Totally agree, but I wasn't suggesting you can't or shouldn't. I just didn't see HMAC as a requirement, hence why I didn't specifically write HMAC.
A MAC is not a "cryptographically secure hash". Nor is SHA-2 somehow not a secure hash because it can't be directly used as a MAC.
This is probably because I completely forgot "cryptographically secure hash" is itself jargon with a wacky definition. To me it was an intuitive concept, but looking it up now, the technical definition isn't what I expected.
In my mind I have both a formal definition of what a "cryptographically secure hash" is (the one I wrote above), and an informal definition: "a hash function that's safe to use anywhere a hash function is needed in cryptography". Regardless of what you think about the formal definition... I would've hoped everyone would agree about the informal one. It only seems reasonable to deduce that from its name. But I guess I'm too naive to think things mean what they say?
So now that you point it out, I hate that definition too. Would be lovely if they changed it to mean what it says on the tin. I doubt that I'll even manage to remember to change my vernacular as a workaround for the wacky technical definition.
We're talking here about one of the very simplest tasks in cryptography, of simply encrypting a discrete message. To steal a rhetorical device from Watson Ladd, after a long discussion that started with a gravely broken system, we arrived at something that might work, and that would almost certainly get you a D in a first undergraduate course.
The experience you'll have trying to design anything more complicated is that, even with a lot of effort and careful thought _and experience_, will be that the first cut of any system you come up with will have vulnerabilities. Of course they will. Look at the track record of (checks) everybody else that has ever tried to ship cryptography.
But the problems you're going to run into aren't going to be described intuitively, in "plain language". Just like being a medical doctor, you need to be conversant with the terminology of the field to understand what the pitfalls are. Very serious vulnerabilities in schemes you come up with are going to be described in the literature in terms of acronyms related to proofs that are themselves stitched together with jargon and acronyms.
Cryptography is hard! I solve this problem for myself by simply refusing to design cryptosystems for other people. It's much easier being a vulnerability researcher that dabbles in cryptography than it is to be a practicing cryptography engineer.
As already mentioned, this allows the attacker to generate a valid hash in some circumstances. You don't have to allow this and it has been argued that such an approach is secure[1].
As a practical example, which is guaranteed to annoy someone just by the suggestion, the OpenPGP authenticated encryption mode that has been around forever has never been subverted in this way but is at its heart "hash then encrypt". It depends on a random value that is kept from attackers[2].
[1] https://cseweb.ucsd.edu/~mihir/papers/enc-red.pdf
[2] https://articles.59.ca/doku.php?id=pgpfan:mdc (my article)
https://raw.githubusercontent.com/pakesson/diy-ecb-penguin/m...