Slide 1

Slide 1 text

Mettre la cryptographie au service de vos apps Symfony #Symfony_Live @nicolasgrekas

Slide 2

Slide 2 text

@nicolasgrekas

Slide 3

Slide 3 text

Le cryptographie • Hacher – à sens unique • Chiffrer – réversible • Intégrité et confidentialité • Stocker et transmettre des données

Slide 4

Slide 4 text

Hachez menu ces mots de passe

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Vous ne voulez pas connaître les mots de passe de vos utilisateurs ! @nicolasgrekas

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Empreinte cryptographique = preuve d’intégrité • Pas de collision connue • Économiquement exorbitant à inverser • e10adc3949ba59abbe56e057f20f883e? • md5(), sha1() • Force brute

Slide 9

Slide 9 text

Salez les mots de passe $sel = bin2hex(random_bytes(8)); $empreinte = $sel.hash('sha256', $sel.$mdp); security: encoders: App\Entity\User: algorithm: sha256

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

L’algo parfait est celui de demain @nicolasgrekas

Slide 16

Slide 16 text

BLAKE 3

Slide 17

Slide 17 text

BLAKE 3

Slide 18

Slide 18 text

Vivre dans l’air du temps • MigratingPasswordEncoder • PasswordUpgraderInterface security: encoders: App\Entity\User: algorithm: auto # ou # algorithm: sodium migrate_from: bcrypt

Slide 19

Slide 19 text

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); } }

Slide 20

Slide 20 text

L’Argon2[id] du futur • $argon2id$v=19$m=999999,t=99,p=1 • Empreintes auto-descriptives = migrations à loisir • Quels paramètres adopter?

Slide 21

Slide 21 text

Comment régler l’algorithme? • 0.5s à 1s de calcul • Mémoire X nombre de processus PHP

Slide 22

Slide 22 text

Votre infra vient de tomber @nicolasgrekas

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

• Pool FPM dédié • Auth0, Google Connect, Facebook Connect, Amazon Cognito • Keycloak • protocoles aPAKE, SPAKE2+EE • WebAuthn Isoler le calcul des empreintes

Slide 25

Slide 25 text

Chiffrer ses secrets

Slide 26

Slide 26 text

• 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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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);

Slide 29

Slide 29 text

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);

Slide 30

Slide 30 text

@nicolasgrekas > config/secrets/dev/dev.GITHUB_API_TOKEN.aebb6a.php

Slide 31

Slide 31 text

@nicolasgrekas $ cat config/secrets/dev/dev.GITHUB_API_TOKEN.aebb6a.php

Slide 32

Slide 32 text

@nicolasgrekas > config/secrets/prod/prod.decrypt.private.php

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

@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

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

•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()

Slide 38

Slide 38 text

RGDP Les données personnelles

Slide 39

Slide 39 text

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.

Slide 40

Slide 40 text

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.

Slide 41

Slide 41 text

Solutions typiques • Chiffrement des données • Cryptographie asymétrique • Rotation des clefs • Documenter et simplifier • etc.

Slide 42

Slide 42 text

Le législateur aligne l’éthique et la technologie \o/

Slide 43

Slide 43 text

No content