Cryptography overview
The world's understanding of cryptography, the guarantees provided, and the practical safety and limitations, is lacking.
Cryptography, and computer security in general, is discussed in terms of some use-cases. A use-case is addressed by combining some primitives, and there's frequently multiple different algorithms which can provide a primitive.
First, let's look at some use-cases:
- I want to do some banking on my bank's website.
- My bank wants to know that my genuine EMV ("Chip and Pin") card is doing a purchase.
- I want to store a big file privately, but only remember a short password.
- I want the recipient to know that it was actually me that wrote an email.
None of these mention cryptography, or even really that security is expected, but the requirement for security is implied by the context.
Let's pick one of these, and have a look at what's involved: "I want to store a big file privately, but only remember a short password.".
This normally comes up with backups. You want to store your data (your family photos?) on someone else's computer (Amazon's?), but you don't trust them. You want to remember a password, and have this password (and only this password) be able to unlock your precious data.
This is normally realised by:
- Making a key from the user's password.
- Using this key to scramble and protect the data.
Those are our two primitives.
After these steps have been applied, it should be impossible for anyone to un-scramble the data without guessing the password. It's also impossible for anyone to modify the data without us realising.
Everything one of our use-cases, and the vast majority of use-cases in the real world, can be built from a small set of primitives. Here's a list, including the two from above:
- Deriving a key from a password.
- Using a key to scramble and protect data.
- Agreeing on a key with an online, remote computer you know nothing about.
- Protecting something, such that it can only be read by someone you know something about.
- Proving you wrote something, given the other computer already knows something about you.
That's it. Those are our operations. Now, we can build the whole world.
But first, a quick note on security: In the modern Internet era, since ~1993 (25 years!), only #5 has ever been practically attacked in any way. The others are practically perfect.
There have been lots of security problems, and things have had to change to remain secure. These have mostly been:
- Computers have got fast enough that it's been possible to increase some of the "security parameters" in some of the primitives, long before computers have practically been fast enough to actually hurt any of the primitives.
- People have used weaker primitives, or kept old or weak systems running long past when they should have been turned off. That, or they have been legally mandated to use these weaker systems.
- Software bugs. The primitives are complicated, built from lots of algorithms, and the algorithms are hard enough to implement correctly on their own. It's hard to test, too! A lot of components are much more complicated than necessary, but we're bad at fixing that.
- Problems with algorithms which don't translate to real world problems for most use-cases, or that are easy to mitigate once discovered, assuming the relevant people actually adopt the mitigations.
Now we understand what we have to build stuff from, let's try and attack the hardest problem: "I want to do some banking on my bank's website."