[关闭]
@romangol 2018-02-11T22:28:59.000000Z 字数 9052 阅读 989

Crypto Best Practices

crypto


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:

  1. The NaCl/libsodium default
  2. Chacha20-Poly1305
  3. AES-GCM

Avoid:

  1. AES-CBC, AES-CTR by itself
  2. Block ciphers with 64-bit blocks such as Blowfish
  3. OFB mode
  4. 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:

  1. Minimum- 128-bit keys
  2. Maximum- 256-bit keys

Avoid:

  1. Constructions with huge keys
  2. Cipher "cascades"
  3. 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:

  1. HMAC-MD5
  2. HMAC-SHA1
  3. Custom "keyed hash" constructions
  4. Complex polynomial MACs
  5. Encrypted hashes
  6. 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:

  1. HMAC-SHA-512/256
  2. HMAC-SHA-512/224
  3. HMAC-SHA-384
  4. HMAC-SHA-224
  5. HMAC-SHA-512
  6. HMAC-SHA-256

Alternately, use in order of preference:

  1. BLAKE2
  2. SHA3-512
  3. SHA3-256

Avoid:

  1. HMAC-SHA-1
  2. HMAC-MD5
  3. MD6
  4. 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:

  1. Userspace random number generators
  2. /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:

  1. scrypt
  2. bcrypt
  3. sha512crypt
  4. sha256crypt
  5. PBKDF2

Avoid:

  1. Plaintext
  2. Naked SHA-2, SHA-1, MD5
  3. Complex homebrew algorithms
  4. 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:

If you have to use RSA, do use RSA-OAEP. But don't use RSA. Use ECC.

Use: NaCl/libsodium

Avoid:

  1. RSA-PKCS1v15
  2. RSAES-OAEP
  3. RSASSA-PSS with MGFI-256,
  4. Really, anything RSA
  5. ElGamal
  6. 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:

  1. 256-bit minimum for ECC/DH Keys
  2. 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:

  1. NaCl/libsodium
  2. Ed25519
  3. RFC6979 (deterministic DSA/ECDSA)

Avoid:

  1. RSA-PKCS1v15
  2. RSASSA-PSS with MGF1+SHA256
  3. Really, anything RSA
  4. Vanilla ECDSA
  5. Vanilla DSA

Diffie-Hellman

This is the trickiest one. Here is roughly the set of considerations:

It sucks that DH (really, "key agreement") is such an important crypto building
block, but it is.

Use, in order of preference:

  1. NaCl/libsodium
  2. 2048-bit Diffie-Hellman Group #14

Avoid:

  1. conventional DH
  2. SRP
  3. J-PAKE
  4. Handshakes and negotiation
  5. Elaborate key negotiation schemes that only use block ciphers
  6. 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:

Avoid:

  1. PolarSSL
  2. GnuTLS
  3. 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:

Here's why you should still use TLS for your custom transport problem:

Use: TLS

Avoid:

  1. Designing your own encrypted transport, which is a genuinely hard
    engineering problem;
  2. Using TLS but in a default configuration, like, with "curl"
  3. Using "curl"
  4. 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:

  1. Google
  2. Apple
  3. Microsoft
  4. Dropbox
  5. Amazon S3
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注