Because CBC mode is easier to implement, you'll find it in far more libraries. And honestly, if your underlying block-cipher is secure (that's the hard part: where your side-channels all exist), then CBC mode is really the easy part and can be safely implemented yourself. It really is that simple.
-----------------
CBC doesn't have authentication. So add on an HMAC. Done. It takes up a few more bytes but that's not a big deal these days.
So use WebCrypto, instead of the cabinet of curiosities that is crypto-js. (Or, better yet, don't do stuff like this at all, because a browser window is simply an awful setting for serious cryptography).
If you're talking about sending these files around via email/messenger, most browsers treat localhost as a secure context, so this doesn't seem like that significant of a limitation.
If you are serving out an encrypted HTML page insecurely, your users are already hosed, because someone on the path could inject a script that sends the password to evil[.]com when they type it in.
Mostly because we have a bloody simple use case in this topic.
HTML uses some Javascript to encrypt a file. Then later, the Javascript decrypts the file and returns it to normal.
This is a "beginner level" cryptography situation. Yes, I know there's all sorts of traps all around the field of cryptography. But I also know that this particular use case is simple enough that beginners can try their hand at it, and probably make something useful. And with low-probability of a critical error.
-------------
Don't write your own AES-GCM implementation. Don't write your own TLS1.2 implementation. Etc. etc. There's all kinds of subtle errors involved. IVs, Padding, side-channels, man-in-the-middle... more than I can count and very subtle to think about.
The fact that this subthread has gone down a rabbit-hole of hypotheticals that are _COMPLETELY IRRELEVANT_ to the use-case discussed in this github is proof enough. The community is a bit rabid over its "advice" on this subject.
> The fact that this subthread has gone down a rabbit-hole of hypotheticals that are _COMPLETELY IRRELEVANT_
I see what you’re saying, but the fact is that these hypotheticals are not irrelevant. They’re important intricacies and potential trip mines associated with implementing your own encryption.
There are a myriad of encryption libraries that have been implemented, reimplemented, and redesigned by various hackers.
In any case, I think reimplementing CBC is absolutely beginner level as far as implementation is concerned. Yes, you can be tripped up by various _uses_ of CBC, but the failure modes are extremely well studied at this point.
Of course, a proper AEAD implementation would avoid that. But AEAD is commonly established today with GCM, which is not beginner level. So now we're trapped. What am I supposed to tell a young programmer who is interested in playing around with encryption on their own?
Perhaps you wish to stop anyone from studying that subject. But on the contrary, I think the only way a programmer can truly learn this stuff is to implement the easiest stuff and try it out themselves from the ground up.
--------
The _proper_ advice, is... don't write your own production encryption. But... if you have to, stick with the simplest implementation that avoids the most common errors (side channels, timing attacks, etc. etc.), and focus on the simplest use cases that have the largest amount of history.
Of course, there's an entire class of crypto-bugs these days are found at the higher levels, in the "use of encryption" (ex: SSL3.0, TLS1.0, TLS1.1, etc. etc.). Nonce reuse, IV generation, in-advertent side channels due to padding oracles, etc. etc.
Even a "perfect" implementation of CBC will come across these crypto-bugs (and is why modern algorithms do focus on AEAD from the ground up these days, which largely avoids the problem).
So yes, there are a lot of traps and footguns in the world of encryption. But that's true of programming in general. Eventually, someone will want to make their own encryption, maybe the library doesn't work out just right (as is in this case: the Crypto-library doesn't have GCM mode implemented), and other modes need to be used. The use of CBC seems to be done properly here for static-HTML encryption.
> What am I supposed to tell a young programmer who is interested in playing around with encryption on their own?
Tell them to stop if they’re trying to do it for anything real, or do it as a toy protect that never sees the light of day. And if they select the latter, then they may as well try GCM.
Tell them to leave encryption writing to the professionals.
This entire subthread started because the github repo here used CBC mode (which was supported by the original writer's crypto library), rather than GCM mode (which was unsupported).
We're well deep into a "professional" discussion about the pros and cons of particular implementation details of cryptography.
------------
Go back to the top. Look at the Github code. See that it uses a crypto-library. What should have the original writer have done differently?
The answer is absolutely not "write their own implementation of GCM". They chose correctly: using a well known, well supported CBC mode of operation with AES. (And IMO, _IF_ CBC mode were unsupported, the correct move would have been to write CBC themselves, as it is far less complex than GCM, which includes GHASH and other such side-channel issues).
There's context to everything. From my understanding of this current situation, the CBC choice was perfectly valid.
This GCM sideshow is a consequence of the project using crypto-js, which is not fit for purpose. If your cryptography library doesn't support any AEADs, replace it with one that does. This is a browser project, so all it actually needs is WebCrypto. The whole discussion on this thread has been super weird. Don't ever encrypt with non-authenticated cipher modes.
So now what?
https://cryptojs.gitbook.io/docs/
Because CBC mode is easier to implement, you'll find it in far more libraries. And honestly, if your underlying block-cipher is secure (that's the hard part: where your side-channels all exist), then CBC mode is really the easy part and can be safely implemented yourself. It really is that simple.
-----------------
CBC doesn't have authentication. So add on an HMAC. Done. It takes up a few more bytes but that's not a big deal these days.