# Things I think I know about Cryptography

### Dave Cridland ・5 min read

I am, as I've said before, not a cryptographer.

Nevertheless, there are some random things I think I know about cryptography.

Here are some. Please feel free to point out errors, or add to them, in the comments.

## Threat Models

Security without a threat model is meaningless. To protect against something, you need to figure out what the something you're protecting against is. This is easier than you might think - most of us are used to working with use-case statements. So some role playing as an attacker and see what you come up with.

"As a fraudster, I want to obtain your credit card details so I can make purchases"

That one, for example, might tell you you want to encrypt credit card details carefully.

## Assume Failure

You're going to try and make that website XSS free, right? No SQL injections here. You'll continually test to ensure that new techniques don't apply (or are mitigated quickly).

But you also need to assume that somehow, the attacker is still going to breach your defences and exfiltrate your entire database. Design accordingly. Data should not be held online unless its needed online. If you can work with one-way hashes, you should do so. If you can remove the data from the online database entirely, then even better.

In military terms, this is known as defence in depth.

## Plaintexts and Plaintext Equivalents

A plaintext is the thing you encrypt, or hash, or whatever.

A plaintext equivalent is where you don't have the plaintext itself, but you do have something that can be used in place.

An example is Digest authentication, where the server's database (can) store a hash of the password - but you can use that to log in just fine.

Plaintext equivalents are deceptive - they do provide a defence against password reuse, for example, but don't provide all the protection you might think.

## Be random, or be identical

Your random number generator has to be truly random. If it isn't - if there's even the slightest pattern detectable - then you are weakening your security. Always be very careful in how your RNG is seeded and used. Cryptography usually uses "Cryptographically Secure Random Number Generators". Hopefully, by not rolling your own crypto, you won't have to worry.

Everything else must be identical. People have successfully extracted useful information from timing, power fluctuations, RF output... So if you decrypt data and it's not right, or your user doesn't exist during authentication, make sure you go through the motions as much as possible. It sounds like it'd be impossible to get anything useful out of a busy system. it's hard, but it's astonishingly easier than you'd think. Even normal comparison functions, often used for comparing hashes, are vulnerable, and allow a cunning attacker to gradually reveal each byte of the hash.

## Hashes are Amazing

Hash functions - cryptographic message digest algorithms, if you prefer - are magic functions which take a bunch of data and spit out a fixed-length hunk of data (the "hash") which is:

- difficult to figure out what the original data is [A "second preimage attack"]
- difficult to find some other data which gives the same hash [A "first preimage attack"], including by accident.

If you're not sure which hash to use, and it's for a security-related reason, use SHA-2 at a length appropriate for your use.

If you're not using it for security, there's lot of much faster hashes.

## Rolling your own crypto

Never do this.

Always use established libraries, and try to use the highest-level existing building blocks possible. Carefully read the documentation for advice on how to maintain security when calling the code.

Rolling your own crypto is universally recognised as bad.

Except as a learning experience.

## RSA Cryptography

RSA keypairs consist of an Encryption Key (the public key) and a Decryption Key (the private key). You can do two things with them:

- Encrypt a message, using the Encryption Key, which only the possessor of the Decryption Key can decrypt.
- Sign a message, by Decrypting it with the Decryption Key. Then anyone can verify the signature by encrypting it with the Encryption Key.

If you're using RSA cryptography, therefore, be sure that you cannot be tricked into signing the exact same data that you've encrypted. Real cryptosystems protect against this (sometimes by using separate keys for encryption and signing).

## Diffie Hellman

Properly called Diffie-Hellman-Merkle. This is a way of creating a shared secret when all communication has to be done across an untrusted channel. It cannot authenticate, though.

Ephemeral Diffie-Hellman, or DHE (or ECDHE for the Elliptic Curve variant) is used to make a throwaway key for just one session, which means an attacker cannot decrypt sessions by obtaining your (static) private key later - or even at the time.

## Elliptic Curve

All cryptography is based around a difficult-to-reverse mathematical function. Diffie-Hellman is normally based around Discrete Logarithms, for example, and RSA is based around Factorization of Large Integers. Elliptic Curve Cryptography is another case, based around something weird that only Mathematicians care about.

The only thing we care about is that it gives much stronger cryptography for a given keysize.

## AES

AES is a symmetric encryption algorithm. It's really strong and fast, but you need to figure out how to agree on a key without anyone else knowing. You can do this by encrypting the key with RSA, or agreeing one using DH (or ECDH).

## XOR

XOR is the cheapest, and best, symmetric encryption algorithm, though it's also the least flexible.

If you can find a perfectly random key, of exactly the same length as your data, XOR is your friend. But you can only use the key once - if you use it more than once it's trivial to get the plaintext data.

## Bits

When cryptographers talk of "bits of security", what they really mean is "how many tries would it take to guess the key as a power of two". No bits of security means you know the key. One bit means you'll take two tries. Two bits is four tries. 10 bits in 1,024 tries. We normally aim for around 128 bits of security, or 340,282,366,920,938,463,463,374,607,431,768,211,456 tries.

In a perfect world, a 128-bit key would yield 128-bits of security, and it more or less does for AES. To get the same from Elliptic Curve cryptography, we need 256 bit keys. RSA would need 3072-bit keys, and classic DH needs 4096-bit keys. 3DES, at 196 bit keys, yields only 112 bits of security - which is why we don't use it anymore.

And yet, we all use AES with 256-bit keys. AES256 is not, mind, twice as strong - it's 128 times as strong, and vastly beyond anyone's reach. So why?

## Quantum Cryptanalysis

We don't have quantum computers yet, but the general consensus is that we probably will, and relatively soon. Some researchers have managed viable algorithms for breaking cryptographic algorithms we currently use.

Shor's Algorithm attacks a number of them, for example, and "solves" the Discrete Logarithm problem used in DH in a pretty practical speed. It also attacks Elliptic Curve. Interestingly, 256-bit ECDH is actually considerably weaker than DH itself as deployed - old-fashioned 4096-bit DH needs a quantum computer half again as powerful as the same strength ECDH.

Other algorithms attack classical cryptography with varying degrees of success - AES, for example, is roughly halved in strength by a quantum attack - which is why we're already doubling it.

## Other stuff

Please add more in the comments. Or just tell me what I got wrong (bound to be something).

Unless it's for password hashing, in which case use bcrypt with a work factor of at least 10.

en.wikipedia.org/wiki/Bcrypt