$30 off During Our Annual Pro Sale. View Details »

Crypto for everyone - libsodium in PHP 7.2

Crypto for everyone - libsodium in PHP 7.2

PHP 7.2 includes the libsodium cryptography library by default in the base language - the first time that a popular language has shipped with strong, modern crypto support as standard. Everyone can build secure apps without the risks of rolling your own crypto or using outdated libraries. So what's in libsodium? What kind of things can you do? What risks remain? You'll get a tour of cryptographic functions, how they have been done in the past, and how to switch to libsodium to give you a security edge.

I gave this talk at ConFoo Montreal 2018.

Marcus Bointon

March 07, 2018
Tweet

More Decks by Marcus Bointon

Other Decks in Programming

Transcript

  1. CRYPTO FOR EVERYONE
    Libsodium in PHP 7.2
    Marcus Bointon
    Synchromedia Limited, Smartmessages.net,
    Radically Open Security, PHPMailer
    @SynchroM

    View Slide

  2. WHAT’S CRYPTO?
    Cryptography
    ➤ Crypto: secret
    ➤ Graphy: writing
    Writing messages that can only be read by
    the intended recipient
    ➤ Confidentiality
    Proving that you wrote a message
    ➤ Authenticity
    Proving that a message has not been
    altered
    ➤ Integrity
    Marcus Bointon @SynchroM

    View Slide

  3. CRYPTOGRAPHIC FUNCTIONS
    0 keys: hashes, PRNGs, key derivation
    ➤ MD5, SHA1, SHA2, BLAKE2, bcrypt, PBKDF2, argon2
    1 key: message authentication codes (MACs), secret key encryption
    ➤ HMAC*, Poly1305, RC4, Blowfish, 3DES, AES, ChaCha20
    2 keys: key exchange, public key encryption, digital signatures
    ➤ Diffie-Hellman, RSA, DSA, ECDSA, EdDSA, PGP
    Related non-crypto: encoding, compression, math operations
    ➤ base64, charsets, gzip, bin2hex, hash_equals
    Marcus Bointon @SynchroM

    View Slide

  4. CORE & EXTENSION CRYPTO IN PHP
    mhash: PHP 4
    mcrypt: PHP 4.0.2 - 7.1
    openssl: PHP 4.0.4
    pecl-gnupg: PHP 4.3
    hash: PHP 5.1.2
    pecl-scrypt: PHP 5.2
    password_hash: PHP 5.5
    hash_equals: PHP 5.6
    CSPRNG: PHP 7.0
    pecl-libsodium: PHP 5.6
    sodium: PHP 7.2
    Marcus Bointon @SynchroM

    View Slide

  5. WHICH EXTENSION TO USE?
    Marcus Bointon @SynchroM
    MCRYPT
    MCRYPT
    SODIUM
    SODIUM
    OPENSSL
    OPENSSL
    SODIUM
    OPENSSL
    MCRYPT

    View Slide

  6. PHP CRYPTO LIBRARIES
    pear crypt_*
    phpseclib/phpseclib
    defuse/php-encryption
    paragonie/sodium_compat
    paragonie/halite
    phpseclib/mcrypt_compat
    zendframework/zend-crypt
    Marcus Bointon @SynchroM

    View Slide

  7. WHAT’S LIBSODIUM?
    NaCl - “Salt”
    ➤ Networking and cryptography library, 2008
    ➤ nacl.cr.yp.to
    ➤ High-performance, legacy-free, heavily scrutinised open-source C library
    ➤ Resistant to many forms of attack & side channels
    Libsodium
    ➤ Fork of NaCl, also open-source, libsodium.org
    ➤ Cross-platform, multiple language bindings, audited code
    ➤ Available in PHP via pecl since 2014, standard in PHP 7.2
    Marcus Bointon @SynchroM

    View Slide

  8. SALTY PEOPLE
    NaCl
    ➤ Daniel J. Bernstein (“DJB”),
    Tanja Lange, Peter Schwabe
    ➤ University of Eindhoven in the
    Netherlands
    ➤ Numerous other contributors
    Marcus Bointon @SynchroM
    Libsodium
    ➤ Frank Denis @jedisct1
    ➤ Developer & photographer in
    Paris
    ➤ pure-ftpd
    ➤ Scott Arciszewski
    @CiPHPerCoder, @ParagonIE
    ➤ Documentation & wisdom!

    View Slide

  9. WHAT’S A SIDE-CHANNEL ATTACK?
    Any attack based on information gained
    from the physical implementation of a
    system, rather than weaknesses in the
    implemented algorithm itself
    Timing, thermal, RF emissions,
    light, sound, power
    Examples: Spectre & meltdown,
    password hash timing, Ethernet
    switch lights
    Marcus Bointon @SynchroM

    View Slide

  10. EXAMPLE: SIDE CHANNEL VULNERABILITY
    //Old, insecure
    $pw = md5($_POST['password']);
    $r = mysqli_query($db, "SELECT id, name FROM users WHERE email =
    [email protected]’ AND password = '$pw'");
    if (count($r) <= 0) die('Go away!');
    //Safe
    $r = mysqli_query($db, "SELECT id, name, password FROM users WHERE email =
    '[email protected]'");
    $f = mysqli_fetch_assoc($r);
    if (!password_verify($_POST['password'], $f['password'])) die('Go away!’);
    //or
    if (!sodium_crypto_pwhash_str_verify($_POST['password'], $f['password']))
    die('Go away!');
    Marcus Bointon @SynchroM

    View Slide

  11. HASHING
    Hash algorithms may be designed for different
    purposes
    ➤ Fast ones for checksumming, verification:
    MD*, SHA*, BLAKE2
    ➤ Slow ones for password hashing: bcrypt,
    scrypt, PBKDF2, Argon2
    Many old apps used weak MD5 for password
    hashes
    ➤ These are very easily cracked/reversed
    Reference implementations – SHA-256 vs
    SHA-512/256
    Argon2i, Argon2d, Argon2id
    When writing new apps, use the strongest
    available; To upgrade, rehash on login
    Marcus Bointon @SynchroM

    View Slide

  12. HASHING WITH SODIUM
    md5(), sha1(), hash() ➜ sodium_crypto_generichash()
    ➤ Uses BLAKE2b
    ➤ As strong as SHA-3, faster than MD5
    crc32(), hash() ➜ sodium_crypto_shorthash()
    ➤ Short hashes are often used for non-crypto purposes
    password_hash() ➜ sodium_crypto_pwhash()
    ➤ Gives you access to Argon2id, everywhere PHP 7.2 runs
    Marcus Bointon @SynchroM

    View Slide

  13. MESSAGE AUTHENTICATION CODES
    Like a hash, but uses a key as well as the
    input data
    Used to authenticate messages
    Most common: HMAC
    ➤ Hash-based message authentication
    code
    ➤ Adds a key to an existing hash
    algorithm
    ➤ HMAC-MD5, HMAC-SHA256, HMAC-
    SHA512-256, HMAC-SHA512/256
    Poly1305
    Marcus Bointon @SynchroM

    View Slide

  14. MACS IN SODIUM
    hash_hmac ➜ sodium_crypto_auth
    $mac = substr(hash_hmac('sha512', $message, $key), 0, 64)
    $mac = bin2hex(sodium_crypto_auth($message, $key))
    hash_equals ➜ crypto_auth_verify
    hash_equals($mac, substr(hash_hmac('sha512', $message, $key), 0,
    64));
    sodium_crypto_auth_verify($mac, $message, $key);
    Marcus Bointon @SynchroM

    View Slide

  15. SECRET-KEY ENCRYPTION
    Encrypt and decrypt with the same key
    ➤ Symmetric cipher
    ➤ Does not guarantee integrity or authenticity
    ➤ Add a MAC to do that
    sodium_crypto_secretbox* functions
    ➤ Combined encrypt-then-MAC
    sodium_crypto_aead_* functions
    ➤ Achieves the same, but more efficiently
    ➤ Uses ChaCha20-Poly1305 or AES256-GCM AEAD ciphers
    Marcus Bointon @SynchroM

    View Slide

  16. SECRET-KEY ENCRYPTION EXAMPLES
    //Encrypt:
    $key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $ciphertext = sodium_crypto_secretbox('test', $nonce, $key);
    $ciphertext = sodium_crypto_aead_chacha20poly1305_encrypt('test', $nonce, $nonce,
    $key);
    //Decrypt:
    $plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
    $plaintext = sodium_crypto_aead_chacha20poly1305_decrypt($ciphertext, $nonce,
    $nonce, $key);
    //Variants:
    sodium_crypto_aead_chacha20poly1305_ietf_encrypt()
    sodium_crypto_aead_xchacha20poly1305_ietf_encrypt()
    //Future:
    sodium_crypto_aead_encrypt();
    Marcus Bointon @SynchroM

    View Slide

  17. PUBLIC-KEY ENCRYPTION
    Sender & receiver each have two keys:
    private & public
    Messages encrypted with a public key can
    be decrypted with a private key
    Critical component of Key Exchange
    ➤ Public key encryption used to exchange
    a secret key, so that faster symmetric
    ciphers can be used
    Popular algorithms: RSA, Diffie-Hellman,
    X25519
    Marcus Bointon @SynchroM

    View Slide

  18. PUBLIC KEY ENCRYPTION IN SODIUM
    sodium_crypto_box_* functions
    Uses X25519 key exchange, XSalsa20 stream cipher, Poly1305 MAC
    Marcus Bointon @SynchroM

    View Slide

  19. EXAMPLE: PUBLIC KEY ENCRYPTION
    On node A:
    $aliceKeypair = sodium_crypto_box_keypair();
    $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeypair);
    $alicePublicKey = sodium_crypto_box_publickey($aliceKeypair);
    On node B:
    $bobKeypair = sodium_crypto_box_keypair();
    $bobSecretKey = sodium_crypto_box_secretkey($bobKeypair);
    $bobPublicKey = sodium_crypto_box_publickey($bobKeypair);
    Sending from Node A to Node B
    $message 'Hi there! :)';
    $aliceToBob = $aliceSecretKey . $bobPublicKey;
    $nonce = random_bytes(24); /* Never repeat this! */
    $ciphertext = $nonce . sodium_crypto_box($message, $nonce, $aliceToBob);
    On Node B, receiving an encrypted message from Node A
    $bobToAlice = $bobSecretKey . $alicePublicKey;
    $nonce = mb_substr($ciphertext, 0, 24, '8bit');
    $encrypted = mb_substr($ciphertext, 24, null, '8bit');
    $decrypted = sodium_crypto_box_open($encrypted, $nonce, $bobToAlice);
    Marcus Bointon @SynchroM

    View Slide

  20. OTHER CRYPTO FUNCTIONS
    Key derivation
    ➤ Avoid using your real, private key, generate one from it and use that instead
    ➤ sodium_crypto_pwhash
    Key exchange
    ➤ sodium_crypto_kx_*
    ➤ Great explanation on Wikipedia!
    Digital Signatures
    ➤ Like using public key encryption backwards
    Marcus Bointon @SynchroM

    View Slide

  21. DOCUMENTATION
    Marcus Bointon @SynchroM

    View Slide

  22. DOCUMENTATION
    Fortunately there are other sources:
    https://download.libsodium.org/doc/
    https://paragonie.com/book/pecl-
    libsodium
    https://paragonie.com/blog/
    ➤ Guide to Building Secure PHP
    Software
    http://www.phptherightway.com
    Marcus Bointon @SynchroM

    View Slide