Nonce: use only once, dammit!
A Nonce, or Initialisation Vector (IV) is a number that is not secret, but must be used only once —or at least once per secret key. Reusing a nonce has the nasty tendency of instantly revealing all associated messages. Here:
cyphertext1 = key_stream XOR plaintext1 cyphertext2 = key_stream XOR plaintext2
From which you can deduce:
cyphertext1 XOR cyphertext2 = plaintext1 XOR plaintext2
That’s right, the key stream just got kicked out of the equation. The attacker can now read the XOR of 2 plaintext messages! They’ll get cracked in no time.
Chacha20 is fast, easy to implement, and immune to timing attacks. Also, its security margin is quite high —to date, only 7 of its 20 rounds are broken. Use it with 256-bit keys. 128 bits are no longer enough for symmetric crypto, and with Chacha, 256-bit keys are just as fast anyway.
The obvious contender would be AES. Don’t use it. Efficient implementations perform input dependent array indexing, which are not constant time. This allows cache timing attacks that recover the key in no time. OpenSSL got around that with some obfuscation, but the security of this obfuscation is unclear.
Poly1305 is one of the few primitives out there that are provably secure. The only way to crack it is to use brute force. Won’t happen with current tech. Most implementations are efficient and immune to timing attacks.
One caveat, though: never use the same secret authentication key on different messages. If the attacker ever get a hold of two such messages, he’ll be able to forge messages of his own. HMAC doesn’t have this problem, but it relies on the security of the underlying hash.
In practice, I recommend an AEAD construction based on Chacha20 and Poly1305. Just change your nonce as usual and you’ll be safe.
This one was a SHA3 finalist. The reason I prefer it to SHA3 itself is its speed: faster than MD5. It’s also relatively simple to implement, and based on Chacha20. And again, immune to timing attacks if you don’t screw up the implementation.
Public key cryptography: Elliptic curve 25519
RSA doesn’t look good. We keep needing larger and larger keys as attacks improve. This is unwieldy and a bit unpredictable. Elliptic curves on the other hand require much smaller keys, and they seem to resist cryptanalysis quite well. Their only drawback is, large quantum computers would instantly break them. Not any time soon, but still, watch out.
25519 is a curve devised by Daniel J. Bernstein, that offers 128 bits of security with a 256-bit key. (For some reason, 128 bits seem to be enough for public key cryptography.) He chose the parameters to make it easy to implement efficiently, in a way that is immune to timing attacks. This process also left very little room for any backdoor, where the inventor may break his own curve more efficiently than brute force. (The NSA is suspected to have weakened some NIST curves by devious choices of constants.)
Password key derivation: Argon2i or Scrypt
Passwords don’t have enough entropy. 128 bits would require 16 random ASCII characters, and nobody memorises that much. You’ll be lucky if the passwords you deal with have more than 60 bits.
A simple hash isn’t enough. You need to slow down the attacker. Ideally, you want to force the attacker to use just as much computing resources as you did for your legitimate checks. You want an algorithm that works so well in your architecture (presumably an x86 or ARM CPU with lots of RAM), that even specialised circuitry won’t give the attacker a significant edge.
Argon2i and Scrypt are what we would call “memory hard” functions. The idea is to make sure one needs lots of memory to compute the hash. And a good deal of time too, sometimes as much as one second. Since memory tend to cost the same everywhere, this kinda ensures the attacker doesn’t spend less resources than you do to compute a single hash.
My personal preference currently goes to Argon2i, which seems to be better than Scrypt, but is younger and less well known.
It’s wonderful to read an article that I can absolutely agree with. Don’t use AES, use Chacha20 and poly1305. Yay!