Rechercher une fonction PHP

Filtres de chiffrement

Avertissement

Cette fonctionnalité est OBSOLÈTE à partir de PHP 7.1.0. Dépendre de cette fonctionnalité est fortement déconseillé.

Les filtres de chiffrement sont particulièrement utiles pour le chiffrement des fichiers/flux.

mcrypt.* et mdecrypt.* fournissent un système de chiffrement symétrique basé sur libmcrypt. Les deux filtres supportent les mêmes algorithmes disponibles avec la bibliothèque mcrypt, sous la forme de la directive mcrypt.ciphernameciphername est le nom du chiffrement qui sera passé à mcrypt_module_open(). Les cinq paramètres suivants sont aussi disponibles :

Paramètres du filtre mcrypt
Paramètre Obligatoire Par défaut Valeurs possibles
mode Optionnel cbc cbc, cfb, ecb, nofb, ofb, stream
algorithms_dir Optionnel ini_get('mcrypt.algorithms_dir') Chemin vers les algorithmes de modules
modes_dir Optionnel ini_get('mcrypt.modes_dir') Chemin vers les modes de modules
iv Obligatoire N/A Généralement 8, 16 ou 32 octets de données binaires. Dépend du chiffrement
key Obligatoire N/A Généralement 8, 16 ou 32 octets de données binaires. Dépend du chiffrement

Exemple #1 Chiffrement/déchiffrement avec Blowfish

<?php
//$key supposé être précédemment généré
$iv_size mcrypt_get_iv_size(MCRYPT_BLOWFISHMCRYPT_MODE_CBC);
$iv mcrypt_create_iv($iv_sizeMCRYPT_DEV_URANDOM);
$fp fopen('encrypted-file.enc''wb');
fwrite($fp$iv);
$opts = array('mode'=>'cbc','iv'=>$iv'key'=>$key);
stream_filter_append($fp'mcrypt.blowfish'STREAM_FILTER_WRITE$opts);
fwrite($fp'message to encrypt');
fclose($fp);

//déchiffrement...
$fp fopen('encrypted-file.enc''rb');
$iv fread($fp$iv_size mcrypt_get_iv_size(MCRYPT_BLOWFISHMCRYPT_MODE_CBC));
$opts = array('mode'=>'cbc','iv'=>$iv'key'=>$key)
stream_filter_append($fp'mdecrypt.blowfish'STREAM_FILTER_READ$opts);
$data rtrim(stream_get_contents($fp));//trims off null padding
fclose($fp);
echo 
$data;
?>

Exemple #2 Chiffrer un fichier en utilisant AES-128 CBC avec SHA256 HMAC en PHP 5.5+

<?php
AES_CBC
::encryptFile($password"plaintext.txt""encrypted.enc");
AES_CBC::decryptFile($password"encrypted.enc""decrypted.txt");

class 
AES_CBC
{
   protected static 
$KEY_SIZES = array('AES-128'=>16,'AES-192'=>24,'AES-256'=>32);
   protected static function 
key_size() { return self::$KEY_SIZES['AES-128']; } //default AES-128
   
public static function encryptFile($password$input_stream$aes_filename){
      
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC);
      
$fin fopen($input_stream"rb");
      
$fc fopen($aes_filename"wb+");
      if (!empty(
$fin) && !empty($fc)) {
         
fwrite($fcstr_repeat("_"32) );//placeholder, SHA256 HMAC will go here later
         
fwrite($fc$hmac_salt mcrypt_create_iv($iv_sizeMCRYPT_DEV_URANDOM));
         
fwrite($fc$esalt mcrypt_create_iv($iv_sizeMCRYPT_DEV_URANDOM));
         
fwrite($fc$iv mcrypt_create_iv($iv_sizeMCRYPT_DEV_URANDOM));
         
$ekey hash_pbkdf2("sha256"$password$esalt$it=1000self::key_size(), $raw=true);
         
$opts = array('mode'=>'cbc''iv'=>$iv'key'=>$ekey);
         
stream_filter_append($fc'mcrypt.rijndael-128'STREAM_FILTER_WRITE$opts);
         
$infilesize 0;
         while (!
feof($fin)) {
            
$block fread($fin8192);
            
$infilesize+=strlen($block);
            
fwrite($fc$block);
         }
         
$block_size mcrypt_get_block_size(MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC);
         
$padding $block_size - ($infilesize $block_size);//$padding is a number from 1-16
         
fwrite($fcstr_repeat(chr($padding), $padding) );//perform PKCS7 padding
         
fclose($fin);
         
fclose($fc);
         
$hmac_raw self::calculate_hmac_after_32bytes($password$hmac_salt$aes_filename);
         
$fc fopen($aes_filename"rb+");
         
fwrite($fc$hmac_raw);//overwrite placeholder
         
fclose($fc);
      }
   }
   public static function 
decryptFile($password$aes_filename$out_stream) {
      
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC);
      
$hmac_raw file_get_contents($aes_filenamefalseNULL,  032);
      
$hmac_salt file_get_contents($aes_filenamefalseNULL32$iv_size);
      
$hmac_calc self::calculate_hmac_after_32bytes($password$hmac_salt$aes_filename);
      
$fc fopen($aes_filename"rb");
      
$fout fopen($out_stream'wb');
      if (!empty(
$fout) && !empty($fc) && self::hash_equals($hmac_raw,$hmac_calc)) {
         
fread($fc32+$iv_size);//skip sha256 hmac and salt
         
$esalt fread($fc$iv_size);
         
$iv    fread($fc$iv_size);
         
$ekey hash_pbkdf2("sha256"$password$esalt$it=1000self::key_size(), $raw=true);
         
$opts = array('mode'=>'cbc''iv'=>$iv'key'=>$ekey);
         
stream_filter_append($fc'mdecrypt.rijndael-128'STREAM_FILTER_READ$opts);
         while (!
feof($fc)) {
            
$block fread($fc8192);
            if (
feof($fc)) {
               
$padding ord($block[strlen($block) - 1]);//assume PKCS7 padding
               
$block substr($block00-$padding);
            }
            
fwrite($fout$block);
         }
         
fclose($fout);
         
fclose($fc);
      }
   }
   private static function 
hash_equals($str1$str2) {
      if(
strlen($str1) == strlen($str2)) {
         
$res $str1 $str2;
         for(
$ret=0,$i strlen($res) - 1$i >= 0$i--) $ret |= ord($res[$i]);
         return !
$ret;
      }
      return 
false;
   }
   private static function 
calculate_hmac_after_32bytes($password$hsalt$filename) {
      static 
$init=0;
      
$init or $init stream_filter_register("user-filter.skipfirst32bytes""FileSkip32Bytes");
      
$stream 'php://filter/read=user-filter.skipfirst32bytes/resource=' $filename;
      
$hkey hash_pbkdf2("sha256"$password$hsalt$iterations=100024$raw=true);
      return 
hash_hmac_file('sha256'$stream$hkey$raw=true);
   }
}
class 
FileSkip32Bytes extends php_user_filter
{
   private 
$skipped=0;
   function 
filter($in$out, &$consumed$closing)  {
      while (
$bucket stream_bucket_make_writeable($in)) {
         
$outlen $bucket->datalen;
         if (
$this->skipped<32){
            
$outlen min($bucket->datalen,32-$this->skipped);
            
$bucket->data substr($bucket->data$outlen);
            
$bucket->datalen $bucket->datalen-$outlen;
            
$this->skipped+=$outlen;
         }
         
$consumed += $outlen;
         
stream_bucket_append($out$bucket);
      }
      return 
PSFS_PASS_ON;
   }
}
class 
AES_128_CBC extends AES_CBC {
   protected static function 
key_size() { return self::$KEY_SIZES['AES-128']; }
}
class 
AES_192_CBC extends AES_CBC {
   protected static function 
key_size() { return self::$KEY_SIZES['AES-192']; }
}
class 
AES_256_CBC extends AES_CBC {
   protected static function 
key_size() { return self::$KEY_SIZES['AES-256']; }
}
Rechercher une fonction PHP

Version en cache

05/11/2024 10:21:30 Cette version de la page est en cache (à la date du 05/11/2024 10:21:30) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.

Document créé le 30/01/2003, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/php-rf-filters.encryption.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.

Références

  1. Consulter le document html Langue du document :fr Manuel PHP : http://php.net

Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.

Table des matières Haut