A lot has been written about cryptography key lengths from academics (e.g. [Lenstra's equation](https://infoscience.epfl.ch/record/164539/files/NPDF-32.pdf)) and various standard committees ([ECRYPT-CSA](http://www.ecrypt.eu.org/csa/documents/D5.4-FinalAlgKeySizeProt.pdf), Germany's [BSI](https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR02102/BSI-TR-02102.pdf?__blob=publicationFile), America's [NIST](https://csrc.nist.gov/Projects/Key-Management/publications), etc.) over the years. Despite the abundance of coverage on this material on the Internet, these resources lack the clarity that we look for when drafting recommendations for software developers and system administrators. Additionally, many of them are showing their age and desperately need to be brought up to speed with a modern understanding of real world cryptography. ## An Important Note About Cryptographic Key Sizes The most important thing to keep in mind about cryptographic key sizes in 2019 is **they don't matter *nearly* as much as the general public likes to think**. Many people in the security industry focus entirely on maximizing the difficulty of a brute force attack, provided they can still achieve their performance goals. They choose the largest possible keys that meet their target benchmarks and feel safer in doing so. Meanwhile, they're not actually making optimal security choices, and may in fact be hurting their own security. We call this **security theater**. In practical terms, beyond a certain threshold (e.g. the 96-bit security level for symmetric encryption), a larger number of possible keys [buys you almost nothing](https://pthree.org/2016/06/19/the-physics-of-brute-force). ### When Key Size Actually Hurts Security Consider these two block ciphers; which is more secure? * **Blowfish**, which supports up to 448-bit keys. * **AES**, which supports up to 256-bit keys. If you chose Blowfish, you fell for the trap. * Blowfish has a **block size** of 64 bits, whereas AES has a block size of 128 bits. * Blowfish is [vulnerable to attacks because of its small block size](https://sweet32.info) that AES is not. * In the real world, AES has hardware acceleration (AES-NI) that makes it very fast while being immune to cache-timing attacks. Blowfish does not have hardware acceleration available. Focusing entirely on key size, while ignoring other important properties of these algorithms, can lead to making sub-optimal security decisions. But what if you have a *ceteris paribus* scenario where you're always using AES, but deciding between using 128-bit and 256-bit keys for your application. Should you always go for the larger key size? The only meaningful difference between the security of AES-128 and AES-256 is the threat of quantum computers. If a practical quantum computer is ever developed, Grover's algorithm breaks 128-bit AES but not 256-bit AES. But in most protocols, your asymmetric cryptography falls faster (a little more than $2^{32}$ time for 2048-bit RSA and 256-bit ECC versus $2^{64}$ time for AES). Since most AES keys are exchanged using asymmetric cryptography, opting for a 256-bit key probably won't be enough to protect your message confidentiality against a quantum attacker. ## Key Sizes and Algorithm Recommendations If you have a cryptography expert on your team who disagrees with any of these recommendations, listen to your expert. They probably know something specific to your needs that this blog post doesn't. ### Asymmetric ("Public Key") Encryption Use, in order of preference: 1. X25519 (for which the key size never changes) then symmetric encryption. 2. ECDH with secp256r1 (for which the key size never changes) then symmetric encryption. 3. RSA with 2048-bit keys. The security of a 256-bit elliptic curve cryptography key is about even with 3072-bit RSA. Although many organizations are recommending migrating from 2048-bit RSA to 3072-bit RSA (or even 4096-bit RSA) in the coming years, don't follow that recommendation. Instead migrate from RSA to elliptic curve cryptography, and then breathe easy while you keep an eye out for post-quantum cryptography recommendations. Additionally, there are a lot of complex issues to consider with [making RSA encryption secure](https://paragonie.com/blog/2018/04/protecting-rsa-based-protocols-against-adaptive-chosen-ciphertext-attacks), but it's a thorny subject and doesn't bear rehashing in this post. You're better off not using RSA if you can help it. > **ECDH: 256-bit keys** > **RSA: 2048-bit keys** ### Asymmetric ("Public Key") Signatures Use, in order of preference: 1. Ed25519 (for which the key size never changes). 2. ECDSA with secp256r1 (for which the key size never changes). 3. RSA with 2048-bit keys. Everything we just said about RSA encryption applies to RSA signatures. > **ECDSA: 256-bit keys** > **RSA: 2048-bit keys** ### Symmetric-Key Encryption Use, in order of preference: 1. XChaCha20-Poly1305 or XSalsa20-Poly1305 (which always have 256-bit keys) 2. AES-GCM-SIV (regardless of key size) 3. ChaCha20-Poly1305 (which always has 256-bit keys) 4. AES-GCM (regardless of key size) If you're using a reputable TLS library (OpenSSL is the most common), any of these options are fine. Feel free to use 256-bit keys for everything, but don't sweat it too bad if you're forced to use 128-bit keys. For application-layer symmetric-key encryption, two additional options should be considered. 5. AES-CTR (regardless of key size) + HMAC-SHA2 (Encrypt then MAC) 6. AES-CBC (regardless of key size) + HMAC-SHA2 (Encrypt then MAC) If you want to use something else, ask your cryptographer. If you don't have a cryptographer, hire one. Don't try to get too creative with encryption unless you have one on your team; and even then, [proceed with caution](https://tonyarcieri.com/all-the-crypto-code-youve-ever-written-is-probably-broken). > **128-bit or 256-bit keys** are both fine, provided you're using one of the options in this list. ### Symmetric-Key Authentication Use HMAC with a SHA2-family hash function, with a key size equal to the hash function size. There's a lot of good options here. Just make sure you're using at least 224-bit keys for SHA-224. More importantly, don't design your own message authentication protocol out of a hash function. Use HMAC. If your symmetric encryption includes Poly1305 authentication, that's great, but it requires expert care to use it safely. Don't use Poly1305 standalone unless you're an expert. > **224-bit, 256-bit, 384-bit, 512-bit** are all good key sizes, provided your algorithm is reasonable. ## Protocol-Specific Recommendations ### HTTPS / TLS Easy mode: Use [Mozilla's Server-Side TLS Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/). Hard mode: Carefully construct your ciphersuite to include ECDHE, CHACHA20-POLY1305, and AES-GCM without much else, then use tools like [Qualys SSL Labs](https://www.ssllabs.com/ssltest) to validate your configuration. More importantly, try to only support TLS 1.2 or newer if you can help it. ### SSH Easy mode: Follow [Mozilla's OpenSSH server configuration guidelines](https://infosec.mozilla.org/guidelines/openssh). Additionally, make sure you're using Ed25519 keys. You can accomplish this by passing `-t ed25519` to `ssh-keygen`. ### VPN Just use [WireGuard](https://www.wireguard.com/). If you're forced to use OpenVPN, there are [some steps you can follow to harden your OpenVPN configuration](https://blog.g3rt.nl/openvpn-security-tips.html). Just know that, generally, the OpenVPN defaults are terrible for security. For example, the default encryption method is Blowfish. WireGuard is leaps and bounds ahead of any other VPN software in 2019. ## General Cryptography Recommendations If you're looking for a general list of Cryptographic Right Answers, rather than an article focused on key lengths, please refer to [this post by Latacora](https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html). # Update An earlier version of this post claimed that there was a hardware limitation that meant AES-NI was only available with 128-bit keys and not 256-bit keys on some processors. This was misinformation that the author accumulated many years ago and perfectly explained a perceived performance issue, but it turns out, is incorrect. The relevant section has been redacted from the article (but persists in the source code for the article).