Cryptographie 101
Pour les programmeurs (PHP)
À propos de moi
Bonjour mon nom est Philippe.
Je suis analyste en sécurité
applicative chez Lightspeed.
Développeur Internet de longue
date, auteur, podcasteur et
conférencier. Je suis spécialisé
dans PHP, Symfony, la sécurité,
la qualité du code et la
performance.
Sécurité PHP 5 et MySQL 5
OWASP Montreal
PHP Quebec
Créateur de jeux de table
Auteur de jeux de rôle
Étymologie
Cryptographie
vient des mots en grec ancien
kruptos (« caché »)
graphein (« écrire »)
Nomenclature
Code : utilisation de la substitution au niveau des
mots ou des phrases pour coder
Coder : action réalisée sur un texte lorsqu’on
remplace un mot ou une phrase par un autre mot,
un nombre ou un symbole
Nomenclature
Chiffrement : transformation à l’aide d’une clé d’un
message en clair (texte clair) en un message
incompréhensible (texte chiffré) pour celui qui ne
dispose pas de la clé de déchiffrement (en anglais
encryption) 
Chiffre : utilisation de la substitution au niveau des
lettres pour coder
Nomenclature
Cryptogramme : Le message chiffré
Cryptosystème : L’algorithme de chiffrement
Nomenclature
Chiffrer : transformation d’un texte clair en un
message incompréhensible
Déchiffrer : transformation d’un message
incompréhensible en un texte clair
Nomenclature
Cryptographie : étymologiquement « écriture
secrète », devenue par extension l’étude de cet art
(donc aujourd’hui la science visant à créer des
cryptogrammes, c’est-à-dire à chiffrer) ;
Nomenclature
Cryptanalyse : science analysant les cryptogrammes
en vue de les décrypter ;
cryptologie : science regroupant la cryptographie et
la cryptanalyse.
Nomenclature
Décrypter : retrouver le message clair
correspondant à un message chiffré sans posséder la
clé de déchiffrement (terme que ne possèdent pas
les anglophones, qui eux « cassent » des codes
secrets)
Crypter/Décrypter
Un peu d’histoire
Utilisé depuis l’antiquité
Plus ancien connus XVIe siècle av. J.‑C
Chiffre de César
décalage de trois lettres dans l’alphabet sur la
gauche, sans clé
Fonctions de hachage
Créé une empreinte d’une chaîne donnée
// 3a46dce77a312a8564495de073fc1d2a
somme de contrôle, empreinte, hash, résumé de
message, condensé, condensat, empreinte
cryptographique
// 39d5668f56394af67c7d349b8cf68e12
Message Digest 5
128 bits ou 32 caractères en notation hexadécimale
Considérer comme faible
echo md5('PHP Québec'), PHP_EOL;
echo hash('md5', 'PHP Québec'), PHP_EOL;
echo md5('PHP Quebec'), PHP_EOL;
echo md5('PHP quebec'), PHP_EOL;
// PHP Québec = d084d695e53020ba70304327ab3bb58c
// PHP Québec = d084d695e53020ba70304327ab3bb58c
// PHP Quebec = 48d9d03b2805898f8cfc927ce9017f59
// PHP Qqebec = 88191610f70b77967e28aac1d4866115
Message Digest 5
128 bits ou 32 caractères en notation hexadécimale
Considérer comme faible
echo md5('PHP Québec'), PHP_EOL;
echo hash('md5', 'PHP Québec'), PHP_EOL;
echo md5('PHP Quebec'), PHP_EOL;
echo md5('PHP quebec'), PHP_EOL;
// PHP Québec = d084d695e53020ba70304327ab3bb58c
// PHP Québec = d084d695e53020ba70304327ab3bb58c
// PHP Quebec = 48d9d03b2805898f8cfc927ce9017f59
// PHP Qqebec = 88191610f70b77967e28aac1d4866115
Secure Hash Algorithm
160 bits ou 40 caractères en notation hexadécimale
Conçue par le NSA
Standard fédéral américain
Sécurité moyenne pour SHA1
Secure Hash Algorithm
160 bits ou 40 caractères en notation hexadécimale
Conçue par le NSA
Standard fédéral américain
Sécurité moyenne pour SHA1
Secure Hash Algorithm
SHA-2
SHA-224
SHA-256
SHA-384
SHA-512
SHA-3
Compétition pour trouver une nouvelle fonction de
hachage
Organiser par « National Institute of Standards
and Technology »
L’algorithme Keccak
BLAKE2
Suite de BLAKE qui était concurrent pour le
SHA-3
Plus rapide que SHA-3, SHA-2, SHA-1 et MD5
Offre une sécurité supérieure à SHA-2
Similaire à celle de SHA-3
Exemple
echo md5('PHP Quebec'), PHP_EOL;
echo md5('php Québec'), PHP_EOL;
echo sha1('PHP Quebec'), PHP_EOL;
echo hash('sha1', 'PHP Quebec'), PHP_EOL;
echo hash('sha256', 'PHP Quebec'), PHP_EOL;
echo hash('sha384', 'PHP Quebec'), PHP_EOL;
echo hash('sha512', 'PHP Quebec'), PHP_EOL;
echo sodium_bin2hex(sodium_crypto_generichash('PHP Quebec')), PHP_EOL;
// md5 = 48d9d03b2805898f8cfc927ce9017f59
// md5 2 = e0c92c1ee16860a00008cde24695ad5f
// sha1 = 771e49084074599af96ec236cc36fbe1c65dfc13
// sha2 = 771e49084074599af96ec236cc36fbe1c65dfc13
// sha256 = 362e5d7cd923e787031a53f0cee3d5c67dc7a70693b1c55dd117a43791ac1387
// sha384 = 9731f6ddbc4aaacf87b93702c76989e97e6797eec0a590254e7e1da3c7a228ee4f217e9e8a0244086a317585142552d6
// sha512 = e95a291f6ff215655bff4bbbfb30235e322fd3c213c63b7fe29501947937e5a5de5d541b07582425c423b8a3e024de496959a6f69024449ad644651c0bfe90fd
// blake2 = 5609a43e8bda4af9dda76f3a97f81f94fd3b358ce7ca0cba3ee99ce0a5d39f6e
Autres fonctions
whirlpool
ripemd320
ripemd256
tiger192,4
tiger192,3
Autres fonctions
whirlpool
ripemd320
ripemd256
tiger192,4
tiger192,3
Attaque
Table de hachage
Table arc-en-ciel
Force brute
Attaque par canal auxiliaire
Attaque par canal auxiliaire
Attaque par sondage
Cryptanalyse acoustique
Analyse d’émanations électromagnétiques
Analyse de consommation
Attaque par analyse du trafic
Attaque par faute
Attaque par prédiction de branches
Attaque temporelle
Salage
Ajout d’une chaîne de caractères à l’information
Sel : Chaîne aléatoire concaténée aux mots de
passe
Hash Message Authentication Code
Code d’authentification de message
Utilise une clé
Façon rapide de faire un hach un peu plus
sécuritaire pour un mot de passe
//f2cf0703419f807767e0b747d32e22b8e73af6e6
echo hash('sha1', 'phpQuébec');
//45e6831fdec7a34f004d9ddc0ba311b8410ecbbc
echo hash_hmac('sha1', 'phpQuébec', 'secret');
//00ee56aa38a935e88704805ec4d2ec5cfb5d78381b146f8c09c6375e89fced7a
echo sodium_bin2hex(sodium_crypto_generichash('phpQuébec', sodium_crypto_generichash_keygen()));
Poly1305
Code d’authentification de message
Disponible en PHP 7.2+
À utiliser seulement lors de chiffrage authentifier
Itération
/**
* @param string $p Mot de passe à protéger
* @param string $s Sel.
* @param int $c Nombre d’itération.
* @param string $secret La valeur secrete à utilisé
* @param string $a Algorithme de hachage.
*
* @return binary Clé dérivée.
*/
function password($p, $s, $c, $secret, $a = 'sha256') {
$dk = $s; // Clé dérivée
// Effectuer itérations
for ($i = 1; $i <= $c; $i++) {
$dk = hash_hmac($a, $dk.$p, $s));
}
return $dk;
}
PBKDF2
Standard de chiffrement pour les mots de passe
PKCS #5
(Public Key Cryptographic Standards), ou
standards de cryptographie à clé publique
RFC 2898
PBKDF2
/**
* PBKDF2 selon RFC 2898.
*
* @param string $p Mot de passe à protéger
* @param string $s Salt.
* @param int $c Nombre d’itération.
* @param int $dkLen Longueur de la clé dérivé.
* @param string $a Algorithme de hachage.
*
* @return binary Clé dérivée.
*/
function pbkdf2($p, $s, $c, $dkLen, $a = 'sha256')
{
}
PBKDF2
function pbkdf2($p, $s, $c, $dkLen, $a = 'sha256') {
$hLen = strlen(hash($a, null, true)); // Longueur du Hash
$l = ceil($dkLen / $hLen); // Nombre de blocs de la clé dérivée.
$dk = ''; // Clé dérivée
for ($block = 1; $block<=$l; $block ++) {
// Hachage initiale pour ce bloc.
$ib = $b = hash_hmac($a, $s . pack('N’, $block), $p, true);
// Effectuer itérations des blocs
for ($i = 1; $i<$c; $i ++) {
// XOR chaque itération
$ib ^= ($b = hash_hmac($a, $b, $p, true));
}
$dk .= $ib;
}
return substr($dk, 0, $dkLen);
}
PBKDF2 PHP 5.5+
$algo = 'sha384';
$salt = random_bytes(32);
$password = 'mot de passe';
$iterations = 1000; // minimum
$longueur = 0; // Toute la longueur de la réponse de l’algo
$raw_output = false;
$hashPassword = hash_pbkdf2($algo, $password, $salt, $iterations, $longueur, $raw_output);
// Pour comparer :
$comparaison = hash_equals($hashPasswordInDB, $userHashPassword);
Scrypt
Fonction de dérivation de clé
Conçu de façon qu’il soit coûteux
en calcul
en mémoire
Bcrypt
Fonction de hachage
Basé sur Blowfish
Utilise un sel 
Fonction adaptative (Itérations)
Itération doit être puissance de 2
BCrypt pour Mot de Passe (PHP 5.5+)
$algo = PASSWORD_DEFAULT; // PASSWORD_BCRYPT en 5.5 à 7.1
$password = 'mot de passe';
$hashPassword = password_hash($algo, $password);
// Pour comparer :
if (password_verify($password, $hashPasswordInDB)) {
// Vérifier si un nouvel algorithme de hachage est disponible ou si le coût a changé
if (password_needs_rehash(hashPasswordInDB, PASSWORD_DEFAULT, $options)) {
// Si c’est le cas, créez un nouveau hash et remplacez l’ancien
$newHash = password_hash($password, PASSWORD_DEFAULT, $options);
}
// Connectez l’utilisateur
}
Argon2
Fonction de dérivation de clé
Gagnante de la Password Hashing
Competition en juillet 2015
Décline en deux versions :
Argon2d
Argon2i
Argon2id}
Argon2 pour Mot de Passe (PHP 7.1+)
$algo = PASSWORD_DEFAULT; // PASSWORD_ARGON2I en 7.2 et PASSWORD_ARGON2ID en 7.3
$password = 'mot de passe';
$hashPassword = password_hash($algo, $password);
// Pour comparer :
if (password_verify($password, $hashPasswordInDB)) {
// Vérifier si un nouvel algorithme de hachage est disponible ou si le coût a changé
if (password_needs_rehash(hashPasswordInDB, PASSWORD_DEFAULT, $options)) {
// Si c’est le cas, créez un nouveau hash et remplacez l’ancien
$newHash = password_hash($password, PASSWORD_DEFAULT, $options);
}
// Connectez l’utilisateur
}
Utilisation pour les mots de passe
PASSWORD_DEFAULT
Sinon selon l’OWASP :
Argon2
PBKDF2
scrypt
bcrypt
Algorithmes de chiffrement faibles
echo str_rot13('PHP 5.3.9'); // CUC 5.3.9
Chiffre de César
ROT13
rotation de 13 caractères, sans clé
Algorithmes de chiffrement faibles
echo str_rot13('PHP 5.3.9'); // CUC 5.3.9
Chiffre de César
ROT13
rotation de 13 caractères, sans clé
Cryptosystème symétrique
Clé secrète
Chiffrer/Déchiffrer
Problème
secret de la clé
Chiffrement par flot
Aussi connu par flux ou en continu
Générateur de nombre pseudo-aléatoire
Opération  : XOR
Chiffrement par bloc
Divise le message à chiffrer en blocs de taille fix
Modes d’opérations
Dictionnaire de codes : « Electronic
codebook » (ECB)
Dictionnaire de codes : « Electronic
codebook » (ECB)
Vecteur d’initialisation
Bloc de bits combiné avec le premier bloc de
données
Conservez-le en tout temps
au début du message
dans un autre champ
Enchaînement des blocs : « Cipher Block
Chaining » (CBC)
Chiffrement à rétroaction :
« Cipher Feedback » (CFB)
Chiffrement basé sur un compteur : « 
CounTeR » (CTR)
Galois/Counter Mode
Algorithmes
Data Encryption Standard (DES)
Clés de 56 bits
Transforme un bloc de 64 bits en un autre bloc de
64 bits
Très faible
MCRYPT_DES
OPENSSL_CIPHER_DES
Data Encryption Standard (DES)
Clés de 56 bits
Transforme un bloc de 64 bits en un autre bloc de
64 bits
Très faible
MCRYPT_DES
OPENSSL_CIPHER_DES
Triple DES
Passe 3x DES sur un bloc de 64 bits
Utilise 2 ou 3 clés de 56 bits
Faible
MCRYPT_3DES (MCRYPT_TRIPLEDES)
OPENSSL_CIPHER_3DES
Triple DES
Passe 3x DES sur un bloc de 64 bits
Utilise 2 ou 3 clés de 56 bits
Faible
MCRYPT_3DES (MCRYPT_TRIPLEDES)
OPENSSL_CIPHER_3DES
RC4
Clé de taille variable, typiquement entre 40 et 256
bits
Utilise un tableau de 256 octets
Chiffrement text clair via XOR en utilisant le
tableau
Utiliser par WEP, WPA et TLS
RC4
Assez faible
MCRYPT_RC4
MCRYPT_ARCFOUR
MCRYPT_ARCFOUR_IV
RC4
Assez faible
MCRYPT_RC4
MCRYPT_ARCFOUR
MCRYPT_ARCFOUR_IV
Advanced Encryption Standard
Rijndael
Standard de chiffrement pour le gouvernement
américain et NSA
WPA2
Inclus dans les CPU Intel i7
Advanced Encryption Standard
Bloc de 128 bits
clés de 128, 192 ou 256 bits.
Recommander : Fort, Standard, Rapide
Rijndael
OPENSSL_CIPHER_AES_128_CBC
OPENSSL_CIPHER_AES_192_CBC
OPENSSL_CIPHER_AES_256_CBC
MCRYPT_RIJNDAEL_128
MCRYPT_RIJNDAEL_192
MCRYPT_RIJNDAEL_256
Exemple avec mcrypt (avant PHP 7.2)
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$cle = "This is a very secret key";
$secret_text = ' I want to encrypt this ';
$encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $cle, $secret_text, MCRYPT_MODE_CBC, $iv);
$vanila_text = mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $cle, $encrypted_text, MCRYPT_MODE_CBC, $iv);
Exemple avec OpenSSL (PHP 7.1+)
$secret_text = 'I want to encrypt this';
$cle = 'my cryptic key';
$encrypted_text = openssl_encrypt($secret_text, 'aes-128-cbc', $cle);
echo $encrypted_text;
$vanila_text = openssl_decrypt($encrypted_text, 'aes-128-cbc', $cle);
echo $vanila_text;
Exemple PHP 7.2+
$message = 'I want to encrypt this';
if (sodium_crypto_aead_aes256gcm_is_available()) {
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
$key = sodium_crypto_aead_aes256gcm_keygen();
$ad = 'Additional (public) data';
$cipherText = sodium_crypto_aead_aes256gcm_encrypt($message, $ad, $nonce, $key);
$clearText = sodium_crypto_aead_aes256gcm_decrypt($cipherText, $ad, $nonce, $key);
if ($clearText === false) {
throw new Exception("Bad cipherText");
}
}
Serpent
bloc de 128 bits
clés de 128, 192 ou 256 bits
Serait plus sécuritaire que AES
Très lent
MCRYPT_SERPENT
Serpent
bloc de 128 bits
clés de 128, 192 ou 256 bits
Serait plus sécuritaire que AES
Très lent
MCRYPT_SERPENT
Twofish
Bloc de 128 bits
clés de 128, 192 ou 256 bits.
Très sécuritaire
MCRYPT_TWOFISH
Twofish
Bloc de 128 bits
clés de 128, 192 ou 256 bits.
Très sécuritaire
MCRYPT_TWOFISH
Salsa20
Chiffrement de flux
ChaCha20
Standard de IETF
XSalsa20
XChaCha
Exemple PHP 7.2+
$message = 'I want to encrypt this';
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
$ad = 'Additional (public) data';
$cipherText = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($message, $ad,$nonce, $key);
$clearText = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($cipherText, $ad, $nonce, $key);
if ($clearText === false) {
throw new Exception("Bad cipherText");
}
Quoi choisir
XChaCha20-Poly1305/XSalsa20-Poly1305 (PHP
7.2+)
ChaCha20-Poly1305 (PHP 7.2+)
AES-GCM (PHP 7.2+)
AES-CTR + HMAC-SHA2 (PHP 7.1+)
AES-CBC + HMAC-SHA2 (PHP 7.1+)
Cryptosystème asymétrique
Utilise deux clés
publiques : chiffrer
privée : déchiffrer
Très lent
Utilisations
SSL/TLS
Signature d’un message
Chiffré Déchiffré But
Public Privé Chiffré
Privé Public Signature
Rivest Shamir Adleman
Utiliser dans SSL/TLS
Signature
Utilisation
openssl_public_encrypt()
openssl_private_decrypt()
openssl_private_encrypt()
openssl_public_decrypt()
Exemple (PHP 7.1+)
$cle_priv = '/dir/vers/prive.pem'
// $motsdepasse est nécessaire si votre clé est cryptée
$res = openssl_pkey_get_private("file://$cle_priv", $motsdepasse);
openssl_private_encrypt($source, $crypttext, $res);
$cle_public = '/dir/vers/public.pem'
$res = openssl_pkey_get_public("file://$cle_public");
openssl_public_decrypt($crypttext, $newsource, $res);
Échange de clés Diffie-Hellman basé sur les
courbes elliptiques
Elliptic curve Diffie–Hellman (ECDH)
Protocole d’échange de clés
Curve25519
X25519 : fonction DH
Ed25519 : système de signature
Curve25519 : courbe elliptique sous-jacente.
Exemple (PHP 7.2+)
$keypair = sodium_crypto_box_keypair();
$bob_box_publickey = sodium_crypto_box_publickey($keypair);
$bob_box_seceretkey = sodium_crypto_box_secretkey($keypair);
$anonymous_message_to_bob = sodium_crypto_box_seal(
$message,
$bob_box_publickey
);
$bob_box_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
$bob_box_seceretkey,
$bob_box_publickey
);
$decrypted_message = sodium_crypto_box_seal_open(
$anonymous_message_to_bob,
$bob_box_kp
);
Questions ?
Si vous voulez discuter sur le
sujet, n’hésitez pas à me contacter.
pres.crypto@ph-il.ca
@philoupedia
philippegamache
Philippe Gamache
https://joind.in/talk/8c69c
Cette présentation a été créée avec Keynote.
L’iconographie est fournie par Keynote et Font
Awesome.
Sauf sur indication contraire, toutes les
photographies sont utilisées sous licence Creative
Commons. Veuillez vous reporter à la diapositive « 
crédits photo » pour plus d’informations.
Cryptographie 101 pour les programmeurs PHP
Copyright © 2005-2019 Philippe Gamache
Cette présentation est mise à disposition selon les
termes de la Licence —. Pour les utilisations non
couvertes par cette licence, veuillez contacter
l’auteur.
Crédits photo
Tous les graphes et les photographies sont utilisés
sous licence Creative Commons.
Les graphes des chiffrements par blocs viennent de
Wikipédia.

Cryptographie 101 Pour les programmeurs (PHP)

  • 1.
  • 2.
    À propos demoi Bonjour mon nom est Philippe. Je suis analyste en sécurité applicative chez Lightspeed. Développeur Internet de longue date, auteur, podcasteur et conférencier. Je suis spécialisé dans PHP, Symfony, la sécurité, la qualité du code et la performance. Sécurité PHP 5 et MySQL 5 OWASP Montreal PHP Quebec Créateur de jeux de table Auteur de jeux de rôle
  • 4.
    Étymologie Cryptographie vient des motsen grec ancien kruptos (« caché ») graphein (« écrire »)
  • 5.
    Nomenclature Code : utilisation dela substitution au niveau des mots ou des phrases pour coder Coder : action réalisée sur un texte lorsqu’on remplace un mot ou une phrase par un autre mot, un nombre ou un symbole
  • 6.
    Nomenclature Chiffrement : transformation àl’aide d’une clé d’un message en clair (texte clair) en un message incompréhensible (texte chiffré) pour celui qui ne dispose pas de la clé de déchiffrement (en anglais encryption)  Chiffre : utilisation de la substitution au niveau des lettres pour coder
  • 7.
    Nomenclature Cryptogramme : Le messagechiffré Cryptosystème : L’algorithme de chiffrement
  • 8.
    Nomenclature Chiffrer : transformation d’untexte clair en un message incompréhensible Déchiffrer : transformation d’un message incompréhensible en un texte clair
  • 9.
    Nomenclature Cryptographie : étymologiquement « écriture secrète »,devenue par extension l’étude de cet art (donc aujourd’hui la science visant à créer des cryptogrammes, c’est-à-dire à chiffrer) ;
  • 10.
    Nomenclature Cryptanalyse : science analysantles cryptogrammes en vue de les décrypter ; cryptologie : science regroupant la cryptographie et la cryptanalyse.
  • 11.
    Nomenclature Décrypter : retrouver lemessage clair correspondant à un message chiffré sans posséder la clé de déchiffrement (terme que ne possèdent pas les anglophones, qui eux « cassent » des codes secrets) Crypter/Décrypter
  • 12.
    Un peu d’histoire Utilisédepuis l’antiquité Plus ancien connus XVIe siècle av. J.‑C Chiffre de César décalage de trois lettres dans l’alphabet sur la gauche, sans clé
  • 13.
    Fonctions de hachage Crééune empreinte d’une chaîne donnée // 3a46dce77a312a8564495de073fc1d2a somme de contrôle, empreinte, hash, résumé de message, condensé, condensat, empreinte cryptographique // 39d5668f56394af67c7d349b8cf68e12
  • 14.
    Message Digest 5 128 bitsou 32 caractères en notation hexadécimale Considérer comme faible echo md5('PHP Québec'), PHP_EOL; echo hash('md5', 'PHP Québec'), PHP_EOL; echo md5('PHP Quebec'), PHP_EOL; echo md5('PHP quebec'), PHP_EOL; // PHP Québec = d084d695e53020ba70304327ab3bb58c // PHP Québec = d084d695e53020ba70304327ab3bb58c // PHP Quebec = 48d9d03b2805898f8cfc927ce9017f59 // PHP Qqebec = 88191610f70b77967e28aac1d4866115
  • 15.
    Message Digest 5 128 bitsou 32 caractères en notation hexadécimale Considérer comme faible echo md5('PHP Québec'), PHP_EOL; echo hash('md5', 'PHP Québec'), PHP_EOL; echo md5('PHP Quebec'), PHP_EOL; echo md5('PHP quebec'), PHP_EOL; // PHP Québec = d084d695e53020ba70304327ab3bb58c // PHP Québec = d084d695e53020ba70304327ab3bb58c // PHP Quebec = 48d9d03b2805898f8cfc927ce9017f59 // PHP Qqebec = 88191610f70b77967e28aac1d4866115
  • 16.
    Secure Hash Algorithm 160 bitsou 40 caractères en notation hexadécimale Conçue par le NSA Standard fédéral américain Sécurité moyenne pour SHA1
  • 17.
    Secure Hash Algorithm 160 bitsou 40 caractères en notation hexadécimale Conçue par le NSA Standard fédéral américain Sécurité moyenne pour SHA1
  • 18.
  • 19.
    SHA-3 Compétition pour trouverune nouvelle fonction de hachage Organiser par « National Institute of Standards and Technology » L’algorithme Keccak
  • 20.
    BLAKE2 Suite de BLAKEqui était concurrent pour le SHA-3 Plus rapide que SHA-3, SHA-2, SHA-1 et MD5 Offre une sécurité supérieure à SHA-2 Similaire à celle de SHA-3
  • 21.
    Exemple echo md5('PHP Quebec'),PHP_EOL; echo md5('php Québec'), PHP_EOL; echo sha1('PHP Quebec'), PHP_EOL; echo hash('sha1', 'PHP Quebec'), PHP_EOL; echo hash('sha256', 'PHP Quebec'), PHP_EOL; echo hash('sha384', 'PHP Quebec'), PHP_EOL; echo hash('sha512', 'PHP Quebec'), PHP_EOL; echo sodium_bin2hex(sodium_crypto_generichash('PHP Quebec')), PHP_EOL; // md5 = 48d9d03b2805898f8cfc927ce9017f59 // md5 2 = e0c92c1ee16860a00008cde24695ad5f // sha1 = 771e49084074599af96ec236cc36fbe1c65dfc13 // sha2 = 771e49084074599af96ec236cc36fbe1c65dfc13 // sha256 = 362e5d7cd923e787031a53f0cee3d5c67dc7a70693b1c55dd117a43791ac1387 // sha384 = 9731f6ddbc4aaacf87b93702c76989e97e6797eec0a590254e7e1da3c7a228ee4f217e9e8a0244086a317585142552d6 // sha512 = e95a291f6ff215655bff4bbbfb30235e322fd3c213c63b7fe29501947937e5a5de5d541b07582425c423b8a3e024de496959a6f69024449ad644651c0bfe90fd // blake2 = 5609a43e8bda4af9dda76f3a97f81f94fd3b358ce7ca0cba3ee99ce0a5d39f6e
  • 22.
  • 23.
  • 24.
    Attaque Table de hachage Tablearc-en-ciel Force brute Attaque par canal auxiliaire
  • 25.
    Attaque par canalauxiliaire Attaque par sondage Cryptanalyse acoustique Analyse d’émanations électromagnétiques Analyse de consommation Attaque par analyse du trafic Attaque par faute Attaque par prédiction de branches Attaque temporelle
  • 26.
    Salage Ajout d’une chaînede caractères à l’information Sel : Chaîne aléatoire concaténée aux mots de passe
  • 27.
    Hash Message AuthenticationCode Code d’authentification de message Utilise une clé Façon rapide de faire un hach un peu plus sécuritaire pour un mot de passe //f2cf0703419f807767e0b747d32e22b8e73af6e6 echo hash('sha1', 'phpQuébec'); //45e6831fdec7a34f004d9ddc0ba311b8410ecbbc echo hash_hmac('sha1', 'phpQuébec', 'secret'); //00ee56aa38a935e88704805ec4d2ec5cfb5d78381b146f8c09c6375e89fced7a echo sodium_bin2hex(sodium_crypto_generichash('phpQuébec', sodium_crypto_generichash_keygen()));
  • 28.
    Poly1305 Code d’authentification demessage Disponible en PHP 7.2+ À utiliser seulement lors de chiffrage authentifier
  • 29.
    Itération /** * @param string$p Mot de passe à protéger * @param string $s Sel. * @param int $c Nombre d’itération. * @param string $secret La valeur secrete à utilisé * @param string $a Algorithme de hachage. * * @return binary Clé dérivée. */ function password($p, $s, $c, $secret, $a = 'sha256') { $dk = $s; // Clé dérivée // Effectuer itérations for ($i = 1; $i <= $c; $i++) { $dk = hash_hmac($a, $dk.$p, $s)); } return $dk; }
  • 30.
    PBKDF2 Standard de chiffrementpour les mots de passe PKCS #5 (Public Key Cryptographic Standards), ou standards de cryptographie à clé publique RFC 2898
  • 31.
    PBKDF2 /** * PBKDF2 selonRFC 2898. * * @param string $p Mot de passe à protéger * @param string $s Salt. * @param int $c Nombre d’itération. * @param int $dkLen Longueur de la clé dérivé. * @param string $a Algorithme de hachage. * * @return binary Clé dérivée. */ function pbkdf2($p, $s, $c, $dkLen, $a = 'sha256') { }
  • 32.
    PBKDF2 function pbkdf2($p, $s,$c, $dkLen, $a = 'sha256') { $hLen = strlen(hash($a, null, true)); // Longueur du Hash $l = ceil($dkLen / $hLen); // Nombre de blocs de la clé dérivée. $dk = ''; // Clé dérivée for ($block = 1; $block<=$l; $block ++) { // Hachage initiale pour ce bloc. $ib = $b = hash_hmac($a, $s . pack('N’, $block), $p, true); // Effectuer itérations des blocs for ($i = 1; $i<$c; $i ++) { // XOR chaque itération $ib ^= ($b = hash_hmac($a, $b, $p, true)); } $dk .= $ib; } return substr($dk, 0, $dkLen); }
  • 33.
    PBKDF2 PHP 5.5+ $algo= 'sha384'; $salt = random_bytes(32); $password = 'mot de passe'; $iterations = 1000; // minimum $longueur = 0; // Toute la longueur de la réponse de l’algo $raw_output = false; $hashPassword = hash_pbkdf2($algo, $password, $salt, $iterations, $longueur, $raw_output); // Pour comparer : $comparaison = hash_equals($hashPasswordInDB, $userHashPassword);
  • 34.
    Scrypt Fonction de dérivationde clé Conçu de façon qu’il soit coûteux en calcul en mémoire
  • 35.
    Bcrypt Fonction de hachage Basésur Blowfish Utilise un sel  Fonction adaptative (Itérations) Itération doit être puissance de 2
  • 36.
    BCrypt pour Motde Passe (PHP 5.5+) $algo = PASSWORD_DEFAULT; // PASSWORD_BCRYPT en 5.5 à 7.1 $password = 'mot de passe'; $hashPassword = password_hash($algo, $password); // Pour comparer : if (password_verify($password, $hashPasswordInDB)) { // Vérifier si un nouvel algorithme de hachage est disponible ou si le coût a changé if (password_needs_rehash(hashPasswordInDB, PASSWORD_DEFAULT, $options)) { // Si c’est le cas, créez un nouveau hash et remplacez l’ancien $newHash = password_hash($password, PASSWORD_DEFAULT, $options); } // Connectez l’utilisateur }
  • 37.
    Argon2 Fonction de dérivationde clé Gagnante de la Password Hashing Competition en juillet 2015 Décline en deux versions : Argon2d Argon2i Argon2id}
  • 38.
    Argon2 pour Motde Passe (PHP 7.1+) $algo = PASSWORD_DEFAULT; // PASSWORD_ARGON2I en 7.2 et PASSWORD_ARGON2ID en 7.3 $password = 'mot de passe'; $hashPassword = password_hash($algo, $password); // Pour comparer : if (password_verify($password, $hashPasswordInDB)) { // Vérifier si un nouvel algorithme de hachage est disponible ou si le coût a changé if (password_needs_rehash(hashPasswordInDB, PASSWORD_DEFAULT, $options)) { // Si c’est le cas, créez un nouveau hash et remplacez l’ancien $newHash = password_hash($password, PASSWORD_DEFAULT, $options); } // Connectez l’utilisateur }
  • 39.
    Utilisation pour lesmots de passe PASSWORD_DEFAULT Sinon selon l’OWASP : Argon2 PBKDF2 scrypt bcrypt
  • 40.
    Algorithmes de chiffrementfaibles echo str_rot13('PHP 5.3.9'); // CUC 5.3.9 Chiffre de César ROT13 rotation de 13 caractères, sans clé
  • 41.
    Algorithmes de chiffrementfaibles echo str_rot13('PHP 5.3.9'); // CUC 5.3.9 Chiffre de César ROT13 rotation de 13 caractères, sans clé
  • 42.
  • 43.
    Chiffrement par flot Aussiconnu par flux ou en continu Générateur de nombre pseudo-aléatoire Opération  : XOR
  • 44.
    Chiffrement par bloc Divisele message à chiffrer en blocs de taille fix Modes d’opérations
  • 45.
    Dictionnaire de codes :« Electronic codebook » (ECB)
  • 46.
    Dictionnaire de codes :« Electronic codebook » (ECB)
  • 47.
    Vecteur d’initialisation Bloc debits combiné avec le premier bloc de données Conservez-le en tout temps au début du message dans un autre champ
  • 48.
    Enchaînement des blocs :« Cipher Block Chaining » (CBC)
  • 49.
  • 50.
    Chiffrement basé surun compteur : «  CounTeR » (CTR)
  • 51.
  • 52.
  • 53.
    Data Encryption Standard(DES) Clés de 56 bits Transforme un bloc de 64 bits en un autre bloc de 64 bits Très faible MCRYPT_DES OPENSSL_CIPHER_DES
  • 54.
    Data Encryption Standard(DES) Clés de 56 bits Transforme un bloc de 64 bits en un autre bloc de 64 bits Très faible MCRYPT_DES OPENSSL_CIPHER_DES
  • 55.
    Triple DES Passe 3xDES sur un bloc de 64 bits Utilise 2 ou 3 clés de 56 bits Faible MCRYPT_3DES (MCRYPT_TRIPLEDES) OPENSSL_CIPHER_3DES
  • 56.
    Triple DES Passe 3xDES sur un bloc de 64 bits Utilise 2 ou 3 clés de 56 bits Faible MCRYPT_3DES (MCRYPT_TRIPLEDES) OPENSSL_CIPHER_3DES
  • 57.
    RC4 Clé de taillevariable, typiquement entre 40 et 256 bits Utilise un tableau de 256 octets Chiffrement text clair via XOR en utilisant le tableau Utiliser par WEP, WPA et TLS
  • 58.
  • 59.
  • 60.
    Advanced Encryption Standard Rijndael Standardde chiffrement pour le gouvernement américain et NSA WPA2 Inclus dans les CPU Intel i7
  • 61.
    Advanced Encryption Standard Blocde 128 bits clés de 128, 192 ou 256 bits. Recommander : Fort, Standard, Rapide
  • 62.
  • 63.
    Exemple avec mcrypt(avant PHP 7.2) $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $cle = "This is a very secret key"; $secret_text = ' I want to encrypt this '; $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $cle, $secret_text, MCRYPT_MODE_CBC, $iv); $vanila_text = mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $cle, $encrypted_text, MCRYPT_MODE_CBC, $iv);
  • 64.
    Exemple avec OpenSSL(PHP 7.1+) $secret_text = 'I want to encrypt this'; $cle = 'my cryptic key'; $encrypted_text = openssl_encrypt($secret_text, 'aes-128-cbc', $cle); echo $encrypted_text; $vanila_text = openssl_decrypt($encrypted_text, 'aes-128-cbc', $cle); echo $vanila_text;
  • 65.
    Exemple PHP 7.2+ $message= 'I want to encrypt this'; if (sodium_crypto_aead_aes256gcm_is_available()) { $nonce = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES); $key = sodium_crypto_aead_aes256gcm_keygen(); $ad = 'Additional (public) data'; $cipherText = sodium_crypto_aead_aes256gcm_encrypt($message, $ad, $nonce, $key); $clearText = sodium_crypto_aead_aes256gcm_decrypt($cipherText, $ad, $nonce, $key); if ($clearText === false) { throw new Exception("Bad cipherText"); } }
  • 66.
    Serpent bloc de 128bits clés de 128, 192 ou 256 bits Serait plus sécuritaire que AES Très lent MCRYPT_SERPENT
  • 67.
    Serpent bloc de 128bits clés de 128, 192 ou 256 bits Serait plus sécuritaire que AES Très lent MCRYPT_SERPENT
  • 68.
    Twofish Bloc de 128bits clés de 128, 192 ou 256 bits. Très sécuritaire MCRYPT_TWOFISH
  • 69.
    Twofish Bloc de 128bits clés de 128, 192 ou 256 bits. Très sécuritaire MCRYPT_TWOFISH
  • 70.
  • 71.
    Exemple PHP 7.2+ $message= 'I want to encrypt this'; $nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES); $key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen(); $ad = 'Additional (public) data'; $cipherText = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($message, $ad,$nonce, $key); $clearText = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($cipherText, $ad, $nonce, $key); if ($clearText === false) { throw new Exception("Bad cipherText"); }
  • 72.
    Quoi choisir XChaCha20-Poly1305/XSalsa20-Poly1305 (PHP 7.2+) ChaCha20-Poly1305(PHP 7.2+) AES-GCM (PHP 7.2+) AES-CTR + HMAC-SHA2 (PHP 7.1+) AES-CBC + HMAC-SHA2 (PHP 7.1+)
  • 73.
    Cryptosystème asymétrique Utilise deuxclés publiques : chiffrer privée : déchiffrer Très lent
  • 74.
    Utilisations SSL/TLS Signature d’un message ChiffréDéchiffré But Public Privé Chiffré Privé Public Signature
  • 75.
    Rivest Shamir Adleman Utiliserdans SSL/TLS Signature
  • 76.
  • 77.
    Exemple (PHP 7.1+) $cle_priv= '/dir/vers/prive.pem' // $motsdepasse est nécessaire si votre clé est cryptée $res = openssl_pkey_get_private("file://$cle_priv", $motsdepasse); openssl_private_encrypt($source, $crypttext, $res); $cle_public = '/dir/vers/public.pem' $res = openssl_pkey_get_public("file://$cle_public"); openssl_public_decrypt($crypttext, $newsource, $res);
  • 78.
    Échange de clésDiffie-Hellman basé sur les courbes elliptiques Elliptic curve Diffie–Hellman (ECDH) Protocole d’échange de clés
  • 79.
    Curve25519 X25519 : fonction DH Ed25519 :système de signature Curve25519 : courbe elliptique sous-jacente.
  • 80.
    Exemple (PHP 7.2+) $keypair= sodium_crypto_box_keypair(); $bob_box_publickey = sodium_crypto_box_publickey($keypair); $bob_box_seceretkey = sodium_crypto_box_secretkey($keypair); $anonymous_message_to_bob = sodium_crypto_box_seal( $message, $bob_box_publickey ); $bob_box_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey( $bob_box_seceretkey, $bob_box_publickey ); $decrypted_message = sodium_crypto_box_seal_open( $anonymous_message_to_bob, $bob_box_kp );
  • 81.
    Questions ? Si vous voulezdiscuter sur le sujet, n’hésitez pas à me contacter. pres.crypto@ph-il.ca @philoupedia philippegamache Philippe Gamache https://joind.in/talk/8c69c Cette présentation a été créée avec Keynote. L’iconographie est fournie par Keynote et Font Awesome. Sauf sur indication contraire, toutes les photographies sont utilisées sous licence Creative Commons. Veuillez vous reporter à la diapositive «  crédits photo » pour plus d’informations. Cryptographie 101 pour les programmeurs PHP Copyright © 2005-2019 Philippe Gamache Cette présentation est mise à disposition selon les termes de la Licence —. Pour les utilisations non couvertes par cette licence, veuillez contacter l’auteur.
  • 82.
    Crédits photo Tous lesgraphes et les photographies sont utilisés sous licence Creative Commons. Les graphes des chiffrements par blocs viennent de Wikipédia.