Lorsque vient le temps de protéger nos données plusieurs options s’offrent à nous. En fait, plus précisément deux options. Il y a d’un côté le hachage et de l’autre l’encryption. Il existe quelques subtilité entre les deux méthodes qui font en sorte que le choix varie selon la situation.

Hachage

Le hachage est le résultat d’un algorithme qui analyse une chaine de caractère pour la rendre incompréhensible à la lecture. Un algorithme de hachage génère une valeur unique à partir de l’entrée envoyé. L’avantage (ou le désavantage selon certain) du hachage c’est qu’une fois encodé, il est pratiquement impossible de retourner en arrière pour connaître la valeur de départ. Autrement dit, c’est un encryptage unidirectionnel.

Le hachage est souvent utilisé pour l’encryptage de mot de passe dans les base de données. En utilisant ce procédé, il est impossible pour un visiteur ou un administrateur de la BD de connaître les mots de passes des utilisateurs.

Il existe présentement deux fonctions de hachage disponible avec PHP soit md5 et sha1. Il est conseillé d’ajouter une chaîne unique à chaque encryptage communément appelé salt. Cette chaîne permettra de ne pas avoir deux fois le même mot de passe dans la bd. Cela augmentera donc notre protection de nos utilisateurs. Cette chaîne doit être un élément propre à chaque utilisateur. Je propose dans le code suivant d’utiliser la fonction uniqid(). On doit par contre enregistrer le salt avec notre nouvel utilisateur dans la db. Comme je le disais plus haut, cet astuce est uniquement pour éviter une duplication des mots de passes.


//un mot de passe
$mdp = '7chd90sh';
echo md5($mdp); //ab96b777b2f826b110fedffaa9d400ed

//avec un salt
$salt = uniqid();
echo md5($salt.$mdp); //94dd45698e51cfe3995eb3a26de09af3

Encryptage

L’encryptage contrairement au hachage permet d’encoder des données et de les décoder. Cela nous permet d’emmagasiner des données tout en sachant que nous allons pouvoir les récupérer au moment opportun sans problème.

Comment encrypter nos données en PHP?

Il existe une librairie dénommée Mcrypt qui permet d’encrypter nos données. Elle utilise les différents algorithmes d’encryptage disponible. Par contre, elle n’est pas disponible sur tous les hébergeurs de site web, surtout les ceux gratuit. Je vous conseils donc de vérifier avec un phpinfo() si vous hébergeurs vous permet d’utiliser la librairie MCrypt. Pour ceux qui ont accès au php.ini de leur serveur, vous n’avez qu’à l’activer. Pour utiliser la librairie MCrypt, nous avons besoin de trois choses essentiel avant même de commencer à coder. Tout d’abord, nous avons besoin d’un algorithme d’encryptage. Ensuite nous avons besoin d’un mode d’encryptions et pour finir il nous faut une clé secrète. Cette clé sera l’élément essentiel qui vous permettra de récupérer vos données encryptés. Si vous perdez cette clé, vous données seront encrypté à jamais. Si vous vous faites voler votre clé, la barrière de sécurité est sérieusement compromise. Je vais vous présenter la classe PHP que j’utilise pour encrypter mes informations privées. Cette classe a été créée pour le livre Pro PHP Security de la maison d’édition Apress. Un livre que je conseil fortement au développeur qui souhaite en apprendre plus sur la sécurité sur le web. Pour commencer voici les déclarations de variables de la classe ainsi que le constructeur de la classe.


public function __construct( $algo='aes' ) {
      switch ( $algo ) {
      case 'aes':
        $algorithme = MCRYPT_RIJNDAEL_256;
        break;
      case 'tripledes':
        $algorithme = MCRYPT_TRIPLEDES;
        break;
      case 'blowfish':
        $algorithme = MCRYPT_BLOWFISH;
        break;
      default:
        // disallow any other algorithm
        exit( "Erreur fatale. Cette classe n'accepte pas l'algorithme : $algo.
               Vous devez utiliser une de ces algo : 'aes','tripledes', ou 'blowfish'." );
      }
      $this->algo = $algorithme;

      // création d'une ressource mcrypt
      $this->mcrypt = mcrypt_module_open( $this->algo, '',  MCRYPT_MODE_CBC, '' );

      // détermine la taile du vecteur d'initialisation selon le couple algo/mode
      $this->ivsize = mcrypt_enc_get_iv_size( $this->mcrypt );

      // détermine la taille maximal de la clé
      $this->maxKeysize = mcrypt_enc_get_key_size( $this->mcrypt );
    }

Ensuite nous devons assigner une clé à notre classe. Cette clé subira plusieurs manipulations qui feront en sorte qu’elle sera encodée dans la mémoire. Elle sera tout d’abord haché pour être ensuite transformé en binaire.


public function setKey( $secret ) {
	  // initialize key
      $key = NULL;

      // Détermine le nombre de block de 32 caractère que nous aurons besoin
      $keyblocks = ceil( ( $this->maxKeysize * 2 ) / 32 );

      // pour chaque block, on doit généré une chaîne passé au md5 qui encodera la clé
      for ( $ix = 0; $ix < $keyblocks; $ix++ ) {
        $key .= md5( $ix . $secret );
      }

      // on "pack" ensuite la clé en mode binaire (2:1 ratio)
      $key = pack( 'H*', $key );

      // on coupe la clé selon la taille maximal de notre algorithme
      $this->key = substr( $key, 0, $this->maxKeysize );
	  $this->keysize = strlen( $this->key );
    }

Après il nous faut une fonction d’encodage et une autre de décodage. Lorsque la donnée sera encodée, on y glisse le vecteur d’initialisation pour permettre d’avoir exactement le même lors du décodage.


public function encrypt( $data ) {
      // génère un vecteur d'initialisation
      $this->iv = mcrypt_create_iv( $this->ivsize, MCRYPT_RAND );

      // inititialisation
      if (mcrypt_generic_init( $this->mcrypt, $this->key, $this->iv ) === -1) {
        $this->__destruct();
        exit( 'Erreur fatale, incapable de créer d\'initialiser l\'encryptage.' );
      }

      // on encrypte
      $ciphertext = mcrypt_generic( $this->mcrypt, $data );

      // on détruit la ressource mcrypt
      mcrypt_generic_deinit( $this->mcrypt );

      // prepend le vecteur d'initialisation
      $out = $this->iv.$ciphertext;

      // encode le text encrypté avec un base64
      // on coupe le texte en block de 64 caractère pour la transmission
      $out = chunk_split( base64_encode( $out ), 64 );

      return $out;
    }

    public function decrypt( $data ) {
      // la ligne doit être en base64
      $input = base64_decode( $data );

      // lon récupère la taille du vecteur d'initialisation contenu dans notre texte encodé
      $this->iv = substr( $input, 0, $this->ivsize );
      $ciphertext = substr( $input, $this->ivsize );

      // initialisation
      if ( mcrypt_generic_init( $this->mcrypt, $this->key, $this->iv ) === -1) {
        $this->__destruct();
        exit( 'Erreur fatale, incapable d\'initialiser la routine d\'encryption.' );
      }

      $out = mdecrypt_generic( $this->mcrypt, $ciphertext );

      // destruction de la ressource
      mcrypt_generic_deinit( $this->mcrypt );

      // on retourne le texte
      return $out;
    }

Pour finir la classe, nous avons besoin d’une fonction de destruction qui détruira la ressource mcrypt et qui réécrira en mémoire la clé secrète et substituant chaque caractère par un X.


public function __destruct() {
      // write over key in memory
      $this->key = str_repeat( 'X', strlen( $this->key ) );

      // free the mcrypt resource
      mcrypt_module_close( $this->mcrypt );
    }

    // end of mcrypt class
  }

Ajouter mon fil RSS à votre agrégateur de contenu préféré.