Créer une classe Crypter avec PHP

Dans cet article, je vais expliquer comment créer une classe PHP qui chiffrera et déchiffrera toutes les données avec un mot de passe donné. C'est un objet programmé et utilise les algorithmes PHP existants.


introduction

Pensez à ce que nous pourrions avoir besoin d'un cours comme celui-ci? Nous voulons chiffrer les données importantes avec un mot de passe pour des raisons de sécurité. Comme nous l'avons déjà mentionné, nous souhaitons également pouvoir décrypter ces données lorsque cela est nécessaire. Pourquoi devriez-vous utiliser des algorithmes symétriques? C'est facile; Lorsque vous proposez un mot de passe envoyé par courrier électronique ou quelque chose du genre, vous avez besoin que le mot de passe soit envoyé en texte brut. Les algorithmes de hachage ne sont pas réversibles. Une fois que vous avez haché une chaîne, vous ne pouvez pas déchiffrer le texte original à partir du hachage.

Peut-être avez-vous déjà entendu parler de MD5? Ce n'est plus vraiment la meilleure option parce que cela a tendance à être dangereux. Il existe des bases de données sur le Web - que je ne veux pas mentionner - qui peuvent être utilisées pour récupérer le texte en clair d'un hachage simplement en tapant le hachage dans un champ de recherche. Donc, vous devriez utiliser quelque chose comme SHA qui a été développé par la NSA (National Security Agency). SHA est l'abréviation de Secure Hash Algorithm et est l'un des algorithmes de hachage les plus sécurisés. Il y en a aussi d'autres, tels que WHIRLPOOL, PANAMA et RIPEMD, mais SHA est actuellement le standard sécurisé des hachages et est utilisé dans de nombreuses applications.


Étape 1: préparation

Je pense qu'il est important de créer une interface. En effet, nous pouvons toujours utiliser les méthodes définies dans l'interface sans y penser, lors de l'instanciation d'un objet d'une classe, qui implémente cette interface..

Quand une classe implémente une interface, elle doit implémenter les méthodes données dans cette interface, sinon il y aura une erreur! Alors voici un exemple:

 interface ICrypter fonction publique Encrypt ($ data); fonction publique Decrypt ($ data);  La classe Crypter implémente ICrypter fonction publique Encrypt ($ data) … fonction publique Decrypt ($ data) …

Comme vous pouvez le constater, l’interface demande aux classes qui implémentent ICrypter avoir la fonction publique Encrypt avec un paramètre $ data. La fonction publique Decrypt a aussi le paramètre $Les données. Vous pouvez l'essayer si la classe manque une des méthodes données dans l'interface, vous obtenez une erreur fatale. Voici un exemple:

Erreur fatale: La classe Crypter contient 1 méthode abstraite et doit donc être déclarée abstraite ou implémenter les méthodes restantes (ICrypter :: Decrypt) dans C: \ www \ Nettuts \ Crypter \ crypter.php à la ligne 32.

Belle erreur non? Vous pouvez donc être sûr que les classes ont vraiment les méthodes!


Étape 2: mot de passe pour le cryptage et le décryptage

Comme je l'ai déjà dit, nous voulons pouvoir utiliser un mot de passe spécifique pour le cryptage et le décryptage. Ce mot de passe doit être accessible pour les fonctions encrypt et decrypt. Nous allons donc définir une variable d'instance, appelée clé, qui est transmise au constructeur. La définition de Clé $ est seulement nécessaire dans le Ccrypteur Classe:

 clé privée $;

Cependant, la définition du constructeur doit être dans l'interface. Par conséquent, cela est également nécessaire dans la classe, car nous devons implémenter tout ce que nous avons défini dans l'interface. L'interface contiendra:

 fonction publique __construct ($ Key);

et la classe:

 fonction publique __construct ($ Key) …

Maintenant que nous savons que nous obtenons une clé, nous pouvons l’utiliser pour chiffrer et déchiffrer!


Étape 3: constructeur

Dans le constructeur, nous devons définir la clé et choisir un algorithme. Nous allons utiliser l'algorithme Blowfish pour cet exemple et l'utiliser comme valeur standard. J'expliquerai un peu plus sur les algorithmes symétriques plus loin dans le texte, mais pour simplifier, nous utiliserons Blowfish. Vous pouvez changer cela plus tard si vous le souhaitez. Nous avons donc besoin d'une autre variable d'instance appelée Algo:

 private $ Algo;

et le constructeur…

 fonction publique __construct ($ Key, $ Algo = MCRYPT_BLOWFISH) $ this-> Key = substr ($ Key, 0, mcrypt_get_key_size ($ Algo, MCRYPT_MODE_ECB)); $ this-> Algo = $ Algo; 

La longueur de la clé dépend de l'algorithme et du mode de cryptage. Dans cet exemple, nous utiliserons le mode ECB. Vous pouvez faire cette variable comme nous l'avons déjà fait avec l'algorithme. Nous utilisons la sous-chaîne de la clé donnée avec la longueur maximale autorisée. Vous pouvez obtenir cette longueur avec le mcrypt_get_key_size fonction qui nécessite l'algorithme et le mode de cryptage comme paramètres.

Maintenant, nous donnons à notre variable d'instance Key la clé correcte pour l'algorithme et affectons notre variable d'instance Algo.

Alors maintenant, nous avons le constructeur. Comme je l’ai dit précédemment, vous pouvez remplacer la valeur standard d’Algo par n’importe quel autre algorithme pris en charge par MCrypt..

Liste des algorithmes supportés par php.net:

  • MCRYPT_3DES
  • MCRYPT_ARCFOUR_IV (libmcrypt> 2.4.x uniquement)
  • MCRYPT_ARCFOUR (libmcrypt> 2.4.x uniquement)
  • MCRYPT_BLOWFISH
  • MCRYPT_CAST_128
  • MCRYPT_CAST_256
  • MCRYPT_CRYPT
  • MCRYPT_DES
  • MCRYPT_DES_COMPAT (libmcrypt 2.2.x uniquement)
  • MCRYPT_ENIGMA (libmcrypt> 2.4.x uniquement, alias pour MCRYPT_CRYPT)
  • MCRYPT_GOST
  • MCRYPT_IDEA (non-libre)
  • MCRYPT_LOKI97 (libmcrypt> 2.4.x uniquement)
  • MCRYPT_MARS (libmcrypt> 2.4.x uniquement, non libre)
  • MCRYPT_PANAMA (libmcrypt> 2.4.x uniquement)
  • MCRYPT_RIJNDAEL_128 (libmcrypt> 2.4.x uniquement)
  • MCRYPT_RIJNDAEL_192 (libmcrypt> 2.4.x uniquement)
  • MCRYPT_RIJNDAEL_256 (libmcrypt> 2.4.x uniquement)
  • MCRYPT_RC2
  • MCRYPT_RC4 (libmcrypt 2.2.x uniquement)
  • MCRYPT_RC6 (libmcrypt> 2.4.x uniquement)
  • MCRYPT_RC6_128 (libmcrypt 2.2.x uniquement)
  • MCRYPT_RC6_192 (libmcrypt 2.2.x uniquement)
  • MCRYPT_RC6_256 (libmcrypt 2.2.x uniquement)
  • MCRYPT_SAFER64
  • MCRYPT_SAFER128
  • MCRYPT_SAFERPLUS (libmcrypt> 2.4.x uniquement)
  • MCRYPT_SERPENT (libmcrypt> 2.4.x uniquement)
  • MCRYPT_SERPENT_128 (libmcrypt 2.2.x uniquement)
  • MCRYPT_SERPENT_192 (libmcrypt 2.2.x uniquement)
  • MCRYPT_SERPENT_256 (libmcrypt 2.2.x uniquement)
  • MCRYPT_SKIPJACK (libmcrypt> 2.4.x uniquement)
  • MCRYPT_TEAN (libmcrypt 2.2.x uniquement)
  • MCRYPT_THREEWAY
  • MCRYPT_TRIPLEDES (libmcrypt> 2.4.x uniquement)
  • MCRYPT_TWOFISH (pour les anciennes versions de mcrypt 2.x ou mcrypt> 2.4.x)
  • MCRYPT_TWOFISH128 (TWOFISHxxx sont disponibles dans les versions 2.x plus récentes, mais pas dans les versions 2.4.x)
  • MCRYPT_TWOFISH192
  • MCRYPT_TWOFISH256
  • MCRYPT_WAKE (libmcrypt> 2.4.x uniquement)
  • MCRYPT_XTEA (libmcrypt> 2.4.x uniquement)

Alors, lequel devrions-nous utiliser lorsque nous voulons utiliser la classe Crypter dans nos produits? Pour le moment, AES est la norme des algorithmes symétriques. Il est utilisé dans de nombreuses applications, mais où est AES? AES a été publié à l'origine sous le nom de Rijndael, qui est répertorié. C'est un algorithme très rapide, mais sécurisé, et il est même rapide avec une taille de clé de 256 bits. Mon conseil est d'utiliser MCRYPT_RIJNDAEL_256 pour vos applications. A titre d'exemple, AES est utilisé dans WPA2, qui est une norme de sécurité pour WLAN..


Étape 4: Passons maintenant au cryptage

Première chose à vérifier: y a-t-il des données à chiffrer? Sinon, vous pouvez continuer et casser le cryptage. Si vous souhaitez utiliser un autre mode de cryptage, vous devez ajouter le code suivant..

 $ iv_size = mcrypt_get_iv_size ($ this-> Algo, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);

Ce iv est utilisé par exemple dans CBC, CFB, OFB et dans certains algorithmes en mode de cryptage STREAM. Si le paramètre n'est pas passé dans ces modes, le iv sera mis à '\ 0'. L'étape suivante consiste à chiffrer les données avec la fonction simple mcrypt_encrypt. Nous avons besoin ici de notre algorithme, de la clé, des données et d’un mode de cryptage. $ iv est optionnel.

 $ crypt = mcrypt_encrypt ($ this-> algo, $ this-> clé, $ data, MCRYPT_MODE_ECB, $ iv);

Enfin, encodez les données chiffrées avec base64_encode et coupez-les avant de les renvoyer..

 return trim (base64_encode ($ crypt));

Nous devons coder en base64 les données chiffrées pour obtenir des données sécurisées pour les URL. Cela est nécessaire car, si vous souhaitez utiliser les données chiffrées, par exemple dans une URL, vous aurez des problèmes avec '&' car il s'agit d'un caractère réservé spécifié dans le RFC. Vous avez donc besoin de quelque chose comme des caractères alphanumériques - autrement dit, des caractères sûrs. Le code base64 fournit ces caractères sécurisés, c'est pourquoi nous l'utilisons. Nous ne savons pas ce qui sera fait avec les données après le cryptage.


Étape 5: le déchiffrement est un chiffrement inversé

Encore une fois, nous posons la même première question. Y a-t-il des données? Si tel est le cas, vous devez coder en base64 les données que nous avons précédemment codées avec base64_encode.

 $ crypt = base64_decode ($ data);

Puis la partie optionnelle avec $ iv.

 $ iv_size = mcrypt_get_iv_size ($ this-> Algo, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);

Décryptage avec la fonction simple mcrypt_decrypt. Ici, nous avons besoin - presque - des mêmes paramètres. La différence est que la fonction de déchiffrement doit accéder aux données cryptées plutôt qu'aux données d'origine. Donc, là encore, nous utilisons l'algorithme, la clé, les données cryptées, le mode de cryptage et l'option iv.

 $ decrypt = mcrypt_decrypt ($ this-> algo, $ this-> clé, $ crypt, MCRYPT_MODE_ECB, $ iv);

Enfin, renvoyez les données découpées et déchiffrées.

 return trim ($ decrypt);

Exemples

Définir un Crypter global. Dans cet exemple, nous utiliserons RIJNDAEL_256 (AES) avec le mot de passe "Any password". Après avoir instancié, vous appelez vos fonctions ou méthodes pour le tester. Ici on appelle la fonction foo et la méthode foo1.

 $ crypter = new Crypter ("Tout mot de passe", MCRYPT_RIJNDAEL_256); foo (); $ foo = new Foo (); $ foo-> foo1 ();

Vous pouvez obtenir votre cryptographe à partir de la variable Superglobal appelée $ GLOBALS. Ceci est un tableau associatif, vous pouvez donc appeler toutes vos variables globales par le nom avec lequel vous les avez définies. Vous pouvez récupérer le $ crypter qui est défini en dehors du bloc foo ou foo1 avec $ GLOBALS ["crypter"]

 function foo () … $ encrypted = $ GLOBALS ["crypter"] -> Encrypt ($ data); $ decrypted = $ GLOBALS ["crypter"] -> Décrypter ($ crypté);… class Foo fonction publique foo1 () … $ encrypted = $ GLOBALS ["crypter"] -> Encrypt ($ data); $ decrypted = $ GLOBALS ["crypter"] -> Decrypt ($ crypté);…

Conclusion

Maintenant, vous avez une classe Crypter complète et vous pouvez chiffrer et déchiffrer autant de fois que vous le souhaitez! Téléchargez le code source complet avec un bel exemple si vous ne voulez pas le taper vous-même. J'espère que vous avez apprécié cet article.