Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Practical Cryptography for Developers

Practical Cryptography for Developers

Presented at Christchurch Ruby on 20 June 2024.

As developers, we encounter cryptography all the time: SSH keys, SSL/TLS certificates, password hashing, JWT signing, and so on. There are plenty of tutorials and libraries to help us. But we're often cargo culting, instead of understanding, and that creates risk. In this talk, I want to try to make cryptography more approachable and intuitive, focusing on the concepts rather than the maths.

Pete Nicholls

June 20, 2024
Tweet

More Decks by Pete Nicholls

Other Decks in Technology

Transcript

  1. June 2024 Christchurch Ruby Pete Nicholls • @aupajo Practical Cryptography

    for Developers Photo by Christian Lendl on Unsplash
  2. ECC XOR CAESAR WOTS RFC KPA CTR SHA QRNG DDH

    DLP QR FPGA ARX RNG CDH TMTO TLS CCA PSS SSL DRBG UDP ECB ECDSA LFSR FHE AEAD DES GCD hash ASIC AE UH HMAC CA GCM nonce WEP CBC SSH TE SIV HTTPS SPN digest IP FSR KDF CMAC IND GNFS ECDLP IV HKDF ciphertext ECDH DH AES salt AES-NI CRT Diff-e API RSA FDH FIPS AKA COA iv CPA FPE CVP SIS Cryptographers Devlepor Cryptography is a difficult domain. We are often cargo cutting without understanding.
  3. ⊕ Ciphers \ Keeping something secret. CSPRNGs, key strength ≠

    bit length, deciding on length, generating, protecting. ⊕ Keys AES, CBC, CTR. ⊕ Encryption Hash functions, keyed hashing, MACs, passwords, GCM. RSA, generating key pairs, PEM, signing, verifying, EC, TLS, JWKS, WebAuthn. ⊕ Public-key cryptography ⊕ Hashing Post-quantum cryptography, advice, resources. ⊕ The End
  4. The Ceaser Cipher is a simple substitution cipher that shifts

    the alphabet by a fixed number of positions.
  5. The Vignère Cipher (1500s) is a cipher that uses a

    keyword to shift the alphabet by a variable number of positions.
  6. In computers, we work with bits. We might agree to

    represent “A” as 65 in decimal, which fits in a byte. We might refer to that in decimal or more commonly hexadecimal.
  7. PRNGs Mersenne Twister Random, rand() Scientific simulations, video games Concerned

    with quality of bits ’ probability distribution based on its output Example Ruby Use Goals Cryptographically Secure PRNGs Fortuna, /dev/urandom SecureRandom Cryptography Concerned with unpredictability based on the underlying operations
  8. Computers are deterministic. They have to simulate randomness using pseudo-random

    number generators (PRNGs). Mersenne Twister Sobol Neiderreiter
  9. The Mersenne Twister, visualised as noise and as a histogram.

    Used in many places, including Python, R, Excel and Random and rand() in Ruby.
  10. 288 age of the universe in nanoseconds search time to

    break one of 1 million 128- bit targets, using 1 million parallel cores at 1 billionth of a second per guess Is a 128-bit key a good choice?
  11. “Moore’s law posits that computing ef fi ciency doubles roughly

    every two years. We can think of this as a loss of one bit of security every two years: if today a $1000 budget allows you to break, say, a 40-bit key in one hour, then Moore’s law says that two years later, you could break a 41-bit key in one hour for the same $1000 budget.” – Serious Cryptography, Jean-Philippe Aumasson
  12. Key size does not always equal security level RSA with

    4096-bit key ≈ 128-bit RSA with 2048-bit key ≈ 90-bit Due to design or because research breakthroughs often lower security over time.
  13. “Nevertheless, to ensure long-term security, you should choose 256-bit security

    or a bit less. Even in a worst-case scenario—the existence of quantum computers[…]—a 256-bit secure scheme is unlikely to be broken in the foreseeable future. More than 256 bits of security is practically unnecessary, except as a marketing device.” – Serious Cryptography, Jean-Philippe Aumasson
  14. Generating a 256-bit key 256 bits 32 bytes 64 hex

    Advice Generate it from a CSRNG Use the right length (i.e. a 256-bit cipher should be given a 256-bit key, not 100) Don ’ t use password-like shh_im_a_secret values Protect it (encrypt it, put it in a password manager)
  15. Generating a 256-bit key Rails 256 bits 32 bytes 64

    hex $ rails secret a45191e0c0c6acfb848a210f4c3ec0ac98c31e44e551f922382 9bd71d0880933d0215180f8e420c878871441e70a66b9cab924 f251835292b58dc3a7534dc9fe
  16. Protect your keys Keep them in a password manager 1Password

    offers a CLI. $ brew install 1password-cli $ op signin $ op read op://app-prod/db/password $ op read --out-file ./key.pem op://app-prod/server/ssh/key.pem
  17. Protect your keys Encrypt them Once you encrypt the key,

    the password is now the point of weakness. Use MFA in a password manager or a CSRNG password. $ rails credentials:edit $ openssl rsa -aes256 -in private.key -out private_with_password.key $ ssh-keygen -p -f ~/.ssh/id_ed25519
  18. The ciphertext is theoretically perfectly indistinguishable provided the key is

    secret, truly random, and as long as the message. Good, right?
  19. Flip a bit in the ciphertext, and the plaintext changes.

    You might not know how, but you can tamper with its integrity. It is malleable.
  20. Advanced Encryption Standard (AES) Published by NIST Built into your

    processor ’ s instruction set It ’ s everywhere – reliable, well researched, widely implemented 128, 192, or 256-bit keys (typically 128-bit) Supersedes DES, which had weaknesses (leading to 3DES) Several modes of operation, but some should be avoided If you ’ re picking your mode of operation, you might be in too deep. Use the abstractions your framework or library offer.
  21. AES: Cipher Block Chain (CBC) Block cipher, encrypts data in

    chunks (e.g. 128-bit blocks) Data is padded to fit nicely into block size Chain: each block is dependent on the last block Used in TLS <1.1, early FileVault, Rails < 5.2 Because each block depends on the output of the last, you need an IV (“initial value” or “initialisation vector”) to start the first block The IV should be generated with a CSRNG There are better options!
  22. AES: Cipher Block Chain (CBC) PKCS is a series of

    related cryptography standards (they are not versions, each # represents a different topic). Don ’ t leak errors to attackers.
  23. AES: Counter Mode (CTR) Turns a block cipher into a

    stream cipher (that still uses blocks) Streaming is useful in contexts where you might not have the entire data (e.g. tuning in halfway through an encrypted video chat) Needs a counter that incremented for each block Needs a nonce (number used only once) that doesn ’ t have to be random but does need to be unique (never used again), for the same reason you can ’ t reuse a key in a one-time pad
  24. Worth mentioning AES-GCM – supported in TLS 1.3, Rails >5.2,

    we ’ ll discuss this soon RC4 – stream cipher, broken, why early WiFi WEP was hacked, TLS <1.2 Salsa20 and its variant ChaCha – stream ciphers, supported in TLS 1.3
  25. Hashing Examples: MD5 (avoid), SHA-1 (avoid), SHA-2 family, SHA-3 family,

    BLAKE2 Unrecoverable, one-way, no ability to decrypt Fixed length (e.g. “a” and the entire works of Shakespeare will both produce the same length hash) Can have collisions 💥 – algorithms focus on attackers not being able to create them Used for file signatures, passwords, integrity, git commits, etc.
  26. Hash functions MD5: avoid, broken in 2005, at best 64-bit

    collision SHA-1: avoid, 160-bit hash, currently about 63-bit security (still used in Git) SHA-2: successor to SHA-1, consists of SHA-224, SHA-256, SHA-384, and SHA-512 SHA-3: a.k.a. Keccak, won 2009 NIST competition, SHA3-224, SHA3-256, SHA3-384, and SHA3-512, not in Ruby stdlib BLAKE2: fast, most popular non-NIST option Some people do not like USA ’ s NIST due to political reasons.
  27. Keyed hashing A hash function that also takes a secret

    key Proof message hasn ’ t been tempered with Used in IPSec, SSH, TLS, OpenID Connect Used by AWS libraries to prove requests are authentic
  28. Keyed hashing: Message Authentication Codes Ruby MACs produce authentication tags

    that can be used to verify the authenticity of a message, encrypted or not.
  29. JSON Web Tokens (JWTs) HMAC-SHA-256(
 base64url(header) + "." + base64url(payload),


    secret
 ) Raw JWT Base64 encoded Signature with shared secret
  30. Hashing: Passwords Argon2id – optimized against GPU-cracking and side-channel resistance,

    use with minimum configuration of 19 MiB of memory, an iteration count of 2, and 1 degree of parallelism. scrypt – a minimum CPU/memory cost parameter of (2^17), a minimum block size of 8 (1024 bytes), and a parallelization parameter of 1 bcrypt – fine for legacy apps, Rails ’ has_secure_password, use a work factor of 10 or more and with a password limit of 72 bytes PBKDF2 – NIST FIPS recommendation, a work factor of 600,000 or more and set with an internal hash function of HMAC-SHA-256 Purpose-built hash functions OWASP recommendations as of June 2024. Will get stale fast.
  31. Hashing: Passwords $2a$ algorithm (upgrade to $2b$) $12$ cost factor

    (212) o9LcEpctQpki0NGGCA15P. salt K/gQZkbf16q/6GHZutkxQAvNgA6DbVW12 hash These functions produce their own secure hashes and store their work factors. You can upgrade the strength for new passwords without breaking old passwords.
  32. Hashing: Passwords Timing attacks: user enumeration User enumeration: if authenticate

    takes a noticeably longer time, then attackers can determine whether a user is registered or not.
  33. Hashing: Passwords Timing attacks: password comparison You should use a

    constant-time function to compare the two hashes. This prevents an early and fast return during string comparison from revealing which part of the hash matched.
  34. Hashing: Passwords Peppering Along with a salt, you can add

    a pepper that will bind all your salts and hashes to an application-level secret. If your database is leaked, attackers won ’ t have the pepper.
  35. AES: Galois Counter Mode (GCM) TLS, HTTP/2, VPNs, SSH, banking

    apps, database encryption, WiFi WPA3, disk encryption, Rails ’ encryption Authenticated Encryption with Associated Data (AEAD) Encrypts and authenticates a message with an encrypt- then-MAC approach Supports some associated data too (e.g. unencrypted headers) 128-bit key and 96-bit nonce (keep nonces unique for keys!) Larger attack surface due to complexity
  36. AES: Galois Counter Mode (GCM) GCM is versatile: it combines

    encryption (using CTR) and authenticates the message (along with optional associated data) with a MAC.
  37. Rivest-Shamir-Adleman (RSA) Separate encryption and decryption keys, asymmetric “Public” key

    can be shared – anyone can use this key to encrypt “Private” key must be kept secret – allows the owner to decrypt You can derive a public key from a private key, no need to store both Use 4096 minimum, avoid 2048 Encrypt private keys with a password TLS, GPG, SSH, PKI, smart cards, banking, some crypto wallets
  38. Remember the one-time pad? The person decrypting needed to be

    sent a copy, which was risky. One technique was to smuggle them in walnuts. RSA solves this issue by letting the encryption key be public without revealing the decryption key.
  39. Privacy Enhanced Mail (PEM) Problem: email in the 80s didn

    ’ t allow attachments or encryption Solution: come up with a convention for encoding bytes that fits in email In your email, type “----BEGIN WHATEVER----”, encode bytes using system below, and end with a bunch of ---- dashes Does the table look familiar? It ’ s where Base64 encoding came from. Data was padded with = so the string length was a multiple of 4. The modern version is base64 url-safe encoding, which ditches the padding and substitutes + for - and / for _.
  40. RSA: Signing data in Ruby $ base64 < signature.sig MtcAUWpseS1/

    mW6mch2zsiYMShO2VRbkqbrqtptH60id8Oh0H1hY9LWTfXGxpVqRY5oJgcOUNT7+jJTel
 …snip…
 cqaEhZhxwNsqv2nd5bo4j1zVHBCokUxn23VdQpPUx1DvPGLabd1HygIhD83XZN8YL2vFQ mlDNNEFCI1gkP0ZBfpxANgeX+/yor8vnZ4VJ0DzQg2xqk= A private key can be used to create a hash signature of any piece of data, as proof that you created it.
  41. RSA: Verifying data in Ruby Anyone can use the public

    key to verify your signature is authentic.
  42. Elliptic Curve Cryptography (ECC) ECC with 256-bit key is stronger

    than RSA with 4096-bit key Theoretically better, but more complex (complexity = risky) Often used with Diffie-Hellman (DH) for key exchange, called ECDH NIST ’ s official curves created by NSA with no justification, suspicious Curve25519, faster and shorter keys without any suspicious Curve25519 used in Chrome, Apple systems, OpenSSH
  43. TLS Too complicated for this talk! Uses all the foundations

    we ’ ve talked about here Uses certificates, which are claims about an organisation, a binary format PEM encoded (X.509) Certificates are chained, each one signed by the previous that conveys their trust to the child Certificate Authorities (CAs) sign the root certs, ship in OSes and browsers Use letsencrypt to generate for free Use TLS 1.3 Miltiadis Fragkidis on Unsplash
  44. JSON Web Tokens (JWTs) RSA-SHA-256(
 base64url(header) + "." + base64url(payload),


    server-public-key
 ) Verify JWT was signed authentically
  45. JSON Web Key Sets (JWKS) GET /.well-known/jwks.json RSA key type,

    key ID, intent for usage, algorithm, n and e values for computing RSA public key, X.509 certificate chain .
  46. JSON Web Key Sets (JWKS) GET /.well-known/jwks.json Elliptic curve key

    type, key ID, intent for usage, algorithm, crv + x + y values for computing curve public key.
  47. WebAuthn Passkeys Web app creates a challenge Client generates a

    private key stored in secure enclave or Trusted Platform Module (i.e. hardware) Server receives public key, signed challenge, and ID for credential Creating a Passkey
  48. WebAuthn Passkeys Sever generates a challenge Client issues OS request

    with certificate ID User authenticates (e.g. biometric) Secure hardware signs challenge with private key Client sends signed challenge (proof of authenticity) Signing in
  49. Post-Quantum Cryptography Potential to break RSA, Diffie-Hellman, and elliptic curve

    – i.e. all the public-key cryptography in widespread use Can ’ t solve NP-complete (or NP-hard) problems: traveling salesman, clique problem, knapsack problem Symmetric algorithms are theoretically safe if we bump up the key size (256-bit likely to be safe) Can ’ t break hash functions Quantum programming is hard and complex, therefore early post-quantum schemes are more likely to broken and offer poor security NP-complete clique problem
  50. Yes, don ’ t roll your own Choose your parameters

    well (keys, key length, nonce, iv) Protect your keys Use solutions designed for the specific problem (e.g. don ’ t use regular hashing for passwords, don ’ t invent your own salt techniques) Don ’ t go overboard (good encryption is fast , as simple as possible, and secure) Keep up to date Use a security standard Advice