Mettre la cryptographie au service de vos apps Symfony

6baa34bc1e5c347b1003f6abe8691de1?s=47 Nicolas Grekas
September 24, 2020

Mettre la cryptographie au service de vos apps Symfony

Hacher les mots de passe, chiffrer les clefs applicatives, voire chiffrer les données elles-mêmes.
Les dernières versions de Symfony mettent tous les outils nécessaires à disposition pour protéger vos utilisateurs contre les fuites ou autres vols de données.

SHA512, Argon2id, BLAKE2/3, ChaCha20-Poly1305, etc. derrière ces noms barbares se cachent des algorithmes qui fondent les nouveaux standards de protection de la vie privée.
Depuis PHP 7.2, l'extension "sodium" donne accès sans difficulté à toute l'intelligence des spécialistes en cryptographie.
Son API volontairement simplifiée est un trésor pour le reste du monde. Tout y est.

Lors de cette conférence, je vous propose de démystifier ces outils et l'utilisation qui en est faite dans Symfony.

6baa34bc1e5c347b1003f6abe8691de1?s=128

Nicolas Grekas

September 24, 2020
Tweet

Transcript

  1. Mettre la cryptographie au service de vos apps Symfony #Symfony_Live

    @nicolasgrekas
  2. @nicolasgrekas

  3. Le cryptographie • Hacher – à sens unique • Chiffrer

    – réversible • Intégrité et confidentialité • Stocker et transmettre des données
  4. Hachez menu ces mots de passe

  5. Les menaces • Fuite de données personnelles Inadvertance ou malveillance

    • Usurpation d’identité sur votre site Préjudice au client et/ou au business (demande de droit d’accès RGDP) • Réutilisation sur des sites tiers Partage de mots de passe entre sites
  6. Vous ne voulez pas connaître les mots de passe de

    vos utilisateurs ! @nicolasgrekas
  7. Mot de passe = jamais en clair, ni chiffré echo

    strlen('123456'); // 6 echo hash('crc32', '123456'); // 158520161 echo hash('md5', '123456'); // e10adc3949ba59abbe56e057f20f883e echo hash('sha256', '123456'); // 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
  8. Empreinte cryptographique = preuve d’intégrité • Pas de collision connue

    • Économiquement exorbitant à inverser • e10adc3949ba59abbe56e057f20f883e? • md5(), sha1() • Force brute
  9. Salez les mots de passe $sel = bin2hex(random_bytes(8)); $empreinte =

    $sel.hash('sha256', $sel.$mdp); security: encoders: App\Entity\User: algorithm: sha256
  10. Augmentez le coût en force brute $sel = bin2hex(random_bytes(8)); $empreinte

    = $sel.hash('sha256', $sel.$mdp); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); $empreinte = $sel.hash('sha256', $sel.$empreinte); security: encoders: App\Entity\User: algorithm: pbkdf2 hash_algorithm: sha256 iterations: 5000
  11. Bcrypt à la rescousse echo password_hash('123456', PASSWORD_BCRYPT, ['cost' => 10]);

    // $2y$10$YHtTDQEjxSIr.UCLmj/JD.VN7UD4hMBOtJNzfdjxW3s1TmcMyaOYK security: encoders: App\Entity\User: algorithm: bcrypt cost: 10
  12. None
  13. Argon2[id] • $argon2id$v=19$m=65536,t=4,p=1 • m=memory t=time p=parallel • Argon2i =

    anti calcul vectoriel Argon2d = anti canal auxiliaire Argon2id = mixe les deux
  14. Argon2[id] echo password_hash('123456', PASSWORD_ARGON2ID); // $argon2id$v=19$m=65536,t=4,p=1$OXhtdDFSLnViTS5zdWx2eQ$OdhFoYQAyyoL security: encoders: App\Entity\User: algorithm:

    sodium
  15. L’algo parfait est celui de demain @nicolasgrekas

  16. BLAKE 3

  17. BLAKE 3

  18. Vivre dans l’air du temps • MigratingPasswordEncoder • PasswordUpgraderInterface security:

    encoders: App\Entity\User: algorithm: auto # ou # algorithm: sodium migrate_from: bcrypt
  19. PasswordUpgraderInterface <3 MakerBundle // ... use Symfony\Component\Security\Core\User\PasswordUpgraderInterface as PUI; class

    UserRepository extends EntityRepository implements PUI { // ... public function upgradePassword(UserInterface $user, string $newPassword) { $user->setPassword($newPassword); $this->getEntityManager()->flush($user); } }
  20. L’Argon2[id] du futur • $argon2id$v=19$m=999999,t=99,p=1 • Empreintes auto-descriptives = migrations

    à loisir • Quels paramètres adopter?
  21. Comment régler l’algorithme? • 0.5s à 1s de calcul •

    Mémoire X nombre de processus PHP
  22. Votre infra vient de tomber @nicolasgrekas

  23. Isoler les calculs d’empreinte du reste de l’application @nicolasgrekas

  24. • Pool FPM dédié • Auth0, Google Connect, Facebook Connect,

    Amazon Cognito • Keycloak • protocoles aPAKE, SPAKE2+EE • WebAuthn Isoler le calcul des empreintes
  25. Chiffrer ses secrets

  26. • Symétrique une même clef pour chiffrer et déchiffrer •

    Asymétrique une clef pour chiffrer, une autre pour déchiffrer Chiffrer = réversible
  27. Libsodium, natif depuis PHP 7.2 sodium_crypto_secretbox_*(); sodium_crypto_box_*(); sodium_crypto_generichash_*(); sodium_crypto_pwhash_*(); sodium_crypto_sign_*();

    sodium_crypto_auth_*(); etc. https://jolicode.com/blog/what-libsodium-can-do-for-you-an-introduction-to-cryptography-in-php
  28. Chiffrement symétrique $key = sodium_crypto_secretbox_keygen(); $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $encrypted =

    sodium_crypto_secretbox('my secret data', $nonce, $key); //... $decrypted = sodium_crypto_secretbox_open($encrypted, $nonce, $key);
  29. Chiffrement asymétrique $keyPair = sodium_crypto_box_keypair(); $privateKey = sodium_crypto_box_secretkey($keyPair); $publicKey =

    sodium_crypto_box_publickey($keyPair); $encrypted = sodium_crypto_box_seal('my secret data', $publicKey); $decrypted = sodium_crypto_box_seal_open($encrypted, $keyPair);
  30. @nicolasgrekas > config/secrets/dev/dev.GITHUB_API_TOKEN.aebb6a.php

  31. @nicolasgrekas $ cat config/secrets/dev/dev.GITHUB_API_TOKEN.aebb6a.php <?php // dev.GITHUB_API_TOKEN.aebb6a on Thu, 21

    Nov 2019 14:31:29 +0100 return "d\x9B\x5D2\xABV\x0B\xE6\xB1\xC2\x25\xCB\x2B\xDAkA\xE4\xC7\x9Cu\x
  32. @nicolasgrekas > config/secrets/prod/prod.decrypt.private.php

  33. Commitez vos secrets! (sauf la master key) @nicolasgrekas

  34. @nicolasgrekas framework: secrets: vault_directory: '%kernel.project_dir%/config/secrets/%kernel.environment%' decryption_env_var: 'base64:default::SYMFONY_DECRYPTION_SECRET' export SYMFONY_DECRYPTION_SECRET=$(php -r

    'echo base64_encode( \ require "config/secrets/prod/prod.decrypt.private.php" );') Configurer son app Symfony
  35. None
  36. None
  37. •michaeldegroot/DoctrineEncryptBundle Encrypted symfony entity's by verified and standardized libraries •paragonie/halite

    High-level cryptography interface powered by libsodium Encrypter toutes les données Symmetric\Crypto::encrypt() / decrypt() Asymmetric\Crypto::seal() / unseal() Asymmetric\Crypto::encrypt / decrypt() Symmetric\Crypto::authenticate() / verify() Asymmetric\Crypto::sign() / verify()
  38. RGDP Les données personnelles

  39. RGPD • La preuve incombe aux entreprises! La CNIL a

    déjà fermé plusieurs startups – 10M€ ou 2% du CA • Chiffrement Une fuite n’est plus à notifier à la CNIL ni aux utilisateurs The authorities must positively consider the use of encryption in their decision on whether and what amount a fine is imposed as per Art. 83(2)(c) of the GDPR.
  40. Risques typiques • Accès distant • Transmissions non sécurisées •

    Hébergement partagé • Erreur de configuration serveur • Turn over • Mauvais cloisonnement des accès • Corruption d’archives • etc.
  41. Solutions typiques • Chiffrement des données • Cryptographie asymétrique •

    Rotation des clefs • Documenter et simplifier • etc.
  42. Le législateur aligne l’éthique et la technologie \o/

  43. None