Nytro Posted July 4, 2017 Report Share Posted July 4, 2017 Symmetric Encryption The only way to encrypt today is authenticated encryption, or "AEAD". ChaCha20-Poly1305 is faster in software than AES-GCM. AES-GCM will be faster than ChaCha20-Poly1305 with AES-NI. Poly1305 is also easier than GCM for library designers to implement safely. AES-GCM is the industry standard. Use, in order of preference: The NaCl/libsodium default Chacha20-Poly1305 AES-GCM Avoid: AES-CBC, AES-CTR by itself Block ciphers with 64-bit blocks such as Blowfish OFB mode RC4, which is comically broken Symmetric Key Length See The Physics of Brute Force to understand why 256-bit keys is more than sufficient. But rememeber: your AES key is far less likely to be broken than your public key pair, so the latter key size should be larger if you're going to obsess about this. Use: Minimum- 128-bit keys Maximum- 256-bit keys Avoid: Constructions with huge keys Cipher "cascades" Key sizes under 128 bits Symmetric Signatures If you're authenticating but not encrypting, as with API requests, don't do anything complicated. There is a class of crypto implementation bugs that arises from how you feed data to your MAC, so, if you're designing a new system from scratch, Google "crypto canonicalization bugs". Also, use a secure compare function. Use: HMAC Avoid: HMAC-MD5 HMAC-SHA1 Custom "keyed hash" constructions Complex polynomial MACs Encrypted hashes Anything CRC Hashing/HMAC Algorithm If you can get away with it you want to use hashing algorithms that truncate their output and sidesteps length extension attacks. Meanwhile: it's less likely that you'll upgrade from SHA-2 to SHA-3 than it is that you'll upgrade from SHA-2 to BLAKE2, which is faster than SHA-3, and SHA-2 looks great right now, so get comfortable and cuddly with SHA-2. Use, in order of preference: HMAC-SHA-512/256 HMAC-SHA-512/224 HMAC-SHA-384 HMAC-SHA-224 HMAC-SHA-512 HMAC-SHA-256 Alternately, use in order of preference: BLAKE2 SHA3-512 SHA3-256 Avoid: HMAC-SHA-1 HMAC-MD5 MD6 EDON-R Random IDs When creating random IDs, numbers, URLs, nonces, initialization vectors, or anything that is random, then you should always use /dev/urandom. Use: /dev/urandom Create: 256-bit random numbers Avoid: Userspace random number generators /dev/random Password Hashing When using scrypt for password hashing, be aware that It is very sensitive to the parameters, making it possible to end up weaker than bcrypt, and suffers from time-memory trade-off (source #1 and source #2). When using bcrypt, make sure to use the following algorithm to prevent the leading NULL byte problem and the 72-character password limit: bcrypt(base64(sha-512(password))) I'd wait a few years, until 2020 or so, before implementing any of the Password Hashing Competition candidates, such as Argon2. They just haven't had the time to mature yet. Use, in order of preference: scrypt bcrypt sha512crypt sha256crypt PBKDF2 Avoid: Plaintext Naked SHA-2, SHA-1, MD5 Complex homebrew algorithms Any encryption algorithm Asymmetric Encryption It's time to stop using vanilla RSA, and start using NaCl/libsodium. Of all the cryptographic "best practices", this is the one you're least likely to get right on your own. NaCl/libsodium has been designed to prevent you from making stupid mistakes, it's highly favored among the cryptographic community, and focuses on modern, highly secure cryptographic primitives. It's time to start using ECC. Here are several reasons you should stop using RSA and switch to elliptic curve software: Progress in attacking RSA --- really, all the classic multiplicative group primitives, including DH and DSA and presumably ElGamal --- is proceeding faster than progress against elliptic curve. RSA (and DH) drag you towards "backwards compatibility" (ie: downgrade-attack compatibility) with insecure systems. Elliptic curve schemes generally don't need to be vigilant about accidentally accepting 768-bit parameters. RSA begs implementors to encrypt directly with its public key primitive, which is usually not what you want to do: not only does accidentally designing with RSA encryption usually forfeit forward-secrecy, but it also exposes you to new classes of implementation bugs. Elliptic curve systems don't promote this particular foot-gun. The weight of correctness/safety in elliptic curve systems falls primarily on cryptographers, who must provide a set of curve parameters optimized for security at a particular performance level; once that happens, there aren't many knobs for implementors to turn that can subvert security. The opposite is true in RSA. Even if you use RSA-OAEP, there are additional parameters to supply and things you have to know to get right. If you have to use RSA, do use RSA-OAEP. But don't use RSA. Use ECC. Use: NaCl/libsodium Avoid: RSA-PKCS1v15 RSAES-OAEP RSASSA-PSS with MGFI-256, Really, anything RSA ElGamal OpenPGP, OpenSSL, BouncyCastle, etc. Asymmetric Key Length As with symmetric encryption, asymmetric encryption key length is a vital security parameter. Academic, private, and government organizations provide different recommendations with mathematical formulas to approimate the minimum key size requirement for security. See BlueKcrypt's Cryptographyc Key Length Recommendation for other recommendations and dates. To protect data up through 2020, it is recommended to meet the minimum requirements for asymmetric key lengths: Method RSA ECC D-H Key D-H Group Lenstra/Verheul 1881 161 151 1881 Lenstra Updated 1387 163 163 1387 ECRYPT II 1776 192 192 1776 NIST 2048 224 224 2048 ANSSI 2048 200 200 2048 BSI 3072 256 256 3072 See also the NSA Fact Sheet Suite B Cryptography and RFC 3766 for additional recommendations and math algorithms for calculating strengths based on calendar year. Personally, I don't see any problem with using 2048-bit RSA/DH group and 256-bit ECC/DH key lengths. So, my recommendation would be: Use: 256-bit minimum for ECC/DH Keys 2048-bit minimum for RSA/DH Group Avoid: Not following the above recommendations. Asymmetric Signatures In the last few years there has been a major shift away from conventional DSA signatures and towards misuse-resistent "deterministic" signature schemes, of which EdDSA and RFC6979 are the best examples. You can think of these schemes as "user-proofed" responses to the Playstation 3 ECDSA flaw, in which reuse of a random number leaked secret keys. Use deterministic signatures in preference to any other signature scheme. Use, in order of preference: NaCl/libsodium Ed25519 RFC6979 (deterministic DSA/ECDSA) Avoid: RSA-PKCS1v15 RSASSA-PSS with MGF1+SHA256 Really, anything RSA Vanilla ECDSA Vanilla DSA Diffie-Hellman This is the trickiest one. Here is roughly the set of considerations: If you can just use Nacl, use Nacl. You don't even have to care what Nacl does. If you can use a very trustworthy library, use Curve25519; it's the modern ECDH curve with the best software support and the most analysis. People really beat the crap out of Curve25519 when they tried to get it standardized for TLS. There are stronger curves, but none supported as well as Curve25519. But don't implement Curve25519 yourself or port the C code for it. If you can't use a very trustworthy library for ECDH but can for DH, use DH-2048 with a standard 2048 bit group, like Colin says, but only if you can hardcode the DH parameters. But don't use conventional DH if you need to negotiate parameters or interoperate with other implementations. If you have to do handshake negotiation or interoperate with older software, consider using NIST P-256, which has very widespread software support. Hardcoded-param DH-2048 is safer than NIST P-256, but NIST P-256 is safer than negotiated DH. But only if you have very trustworthy library support, because NIST P-256 has some pitfalls. P-256 is probably the safest of the NIST curves; don't go down to -224. Isn't crypto fun? If your threat model is criminals, prefer DH-1024 to sketchy curve libraries. If your threat model is governments, prefer sketchy curve libraries to DH-1024. But come on, find a way to one of the previous recommendations. It sucks that DH (really, "key agreement") is such an important crypto building block, but it is. Use, in order of preference: NaCl/libsodium 2048-bit Diffie-Hellman Group #14 Avoid: conventional DH SRP J-PAKE Handshakes and negotiation Elaborate key negotiation schemes that only use block ciphers srand(time()) Website security By "website security", we mean "the library you use to make your web server speak HTTPS". Believe it or not, OpenSSL is still probably the right decision here, if you can't just delegate this to Amazon and use HTTPS elastic load balancers, which makes this their problem not yours. Use: OpenSSL, LibreSSL, or BoringSSL if you run your own site Amazon AWS Elastic Load Balancing if Amazon does Avoid: PolarSSL GnuTLS MatrixSSL Client-server application security What happens when you design your own custom RSA protocol is that 1-18 months afterwards, hopefully sooner but often later, you discover that you made a mistake and your protocol had virtually no security. A good example is Salt Stack. Salt managed to deploy e=1 RSA. It seems a little crazy to recommend TLS given its recent history: The Logjam DH negotiation attack The FREAK export cipher attack The POODLE CBC oracle attack The RC4 fiasco The CRIME compression attack The Lucky13 CBC padding oracle timing attack The BEAST CBC chained IV attack Heartbleed Renegotiation Triple Handshakes Compromised CAs Here's why you should still use TLS for your custom transport problem: Many of these attacks only work against browsers, because they rely on the victim accepting and executing attacker-controlled Javascript in order to generate repeated known/chosen plaintexts. Most of these attacks can be mitigated by hardcoding TLS 1.2+, ECDHE and AES-GCM. That sounds tricky, and it is, but it's less tricky than designing your own transport protocol with ECDHE and AES-GCM! In a custom transport scenario, you don't need to depend on CAs: you can self-sign a certificate and ship it with your code, just like Colin suggests you do with RSA keys. Use: TLS Avoid: Designing your own encrypted transport, which is a genuinely hard engineering problem; Using TLS but in a default configuration, like, with "curl" Using "curl" IPSEC Online backups Of course, you should host your own backups in house. The best security is the security where others just don't get access to your data. There are many tools to do this, all of which should be using OpenSSH or TLS for the transport. If using an online backup service, use Tarsnap. It's withstood the test of time. Use: Tarsnap Avoid: Google Apple Microsoft Dropbox Amazon S3 Sursa: https://gist.github.com/atoponce/07d8d4c833873be2f68c34f9afc5a78a 2 Quote Link to comment Share on other sites More sharing options...