web-dev-qa-db-fra.com

Cryptage bidirectionnel en PHP

Mon application utilise (évidemment) un identifiant unique pour distinguer les enregistrements. Cet UID est transmis dans les URL (par exemple, ./examplepage.php?UID=$example_int), entre autres.

Bien que j'ai évidemment une validation côté serveur en place pour m'assurer que les clients n'accèdent pas aux données des autres clients, existe-t-il une méthode de cryptage bidirectionnelle que je peux utiliser dans PHP pour ne transmettre que les UID cryptés (par exemple ./examplepage.php?EUID=$encrypted_int), pour réduire davantage les chances de quiconque pense "hé, que se passe-t-il si j'incrémente cet entier?"

TIA.

29
benjy

PHP 5.3 a introduit une nouvelle méthode de cryptage très simple à utiliser: openssl_encrypt Et openssl_decrypt. Ce n'est pas bien documenté ici, alors voici un exemple simple:

$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash);

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);

//Result
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";

J'ai choisi 256-AES car il est solide et rapide. Il a été adopté par le gouvernement américain pour crypter les documents les plus secrets. C'est rapide compte tenu de la machine et du logiciel. Voici une liste des méthodes de cryptage disponibles:

AES-128-CBC, AES-128-CFB, AES-128-CFB1, AES-128-CFB8, AES-128-ECB, AES-128-OFB, AES-192-CBC, AES-192-CFB, AES- 192-CFB1, AES-192-CFB8, AES-192-ECB, AES-192-OFB, AES-256-CBC, AES-256-CFB, AES-256-CFB1, AES-256-CFB8, AES-256- BCE, AES-256-OFB, BF-CBC, BF-CFB, BF-ECB, BF-OFB, CAMELLIA-128-CBC, CAMELLIA-128-CFB, CAMELLIA-128-CFB1, CAMELLIA-128-CFB8, CAMELLIA- 128-ECB, CAMELLIA-128-OFB, CAMELLIA-192-CBC, CAMELLIA-192-CFB, CAMELLIA-192-CFB1, CAMELLIA-192-CFB8, CAMELLIA-192-ECB, CAMELLIA-192-OFB, CAMELLIA-256- CBC, CAMELLIA-256-CFB, CAMELLIA-256-CFB1, CAMELLIA-256-CFB8, CAMELLIA-256-ECB, CAMELLIA-256-OFB, CAST5-CBC, CAST5-CFB, CAST5-ECB, CAST5-OFB, DES- CBC, DES-CFB, DES-CFB1, DES-CFB8, DES-ECB, DES-EDE, DES-EDE-CBC, DES-EDE-CFB, DES-EDE-OFB, DES-EDE3, DES-EDE3-CBC, DES-EDE3-CFB, DES-EDE3-CFB1, DES-EDE3-CFB8, DES-EDE3-OFB, DES-OFB, DESX-CBC, RC2-40-CBC, RC2-64-CBC, RC2-CBC, RC2- CFB, RC2-ECB, RC2-OFB, RC4, RC4-40, SEED-CBC, SEED-CFB, SEED-ECB, SEED-OFB, aes-128-cbc, aes-128-cfb, aes-128-cfb1, aes-1 28-cfb8, aes-128-ecb, aes-128-ofb, aes-192-cbc, aes-192-cfb, aes-192-cfb1, aes-192-cfb8, aes-192-ecb, aes-192- ofb, aes-256-cbc, aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-ecb, aes-256-ofb, bf-cbc, bf-cfb, bf-ecb, bf-ofb, camellia-128-cbc, camellia-128-cfb, camellia-128-cfb1, camellia-128-cfb8, camellia-128-ecb, camellia-128-ofb, camellia-192-cbc, camellia-192- cfb, camellia-192-cfb1, camellia-192-cfb8, camellia-192-ecb, camellia-192-ofb, camellia-256-cbc, camellia-256-cfb, camellia-256-cfb1, camellia-256-cfb8, camellia-256-ecb, camellia-256-ofb, cast5-cbc, cast5-cfb, cast5-ecb, cast5-ofb, des-cbc, des-cfb, des-cfb1, des-cfb8, des-ecb, des- ede, des-ede-cbc, des-ede-cfb, des-ede-ofb, des-ede3, des-ede3-cbc, des-ede3-cfb, des-ede3-cfb1, des-ede3-cfb8, des- ede3-ofb, des-ofb, desx-cbc, rc2-40-cbc, rc2-64-cbc, rc2-cbc, rc2-cfb, rc2-ecb, rc2-ofb, rc4, rc4-40, seed-cbc, graine-cfb, graine-ecb, graine-ofb


MISE À JOUR IMPORTANTE !!!

Merci Hobo et Jorwin d'avoir souligné que dans PHP 5.3.3> il y a un nouveau paramètre qui rend cette fonction un peu plus sécurisée.

Jorwin a référencé ce lien dans son commentaire , et voici un extrait qui est applicable:

Dans 5.3.3, ils ont ajouté un nouveau paramètre, string $iv (Vecteur d'initialisation) Les paramètres réels sont: string openssl_encrypt ( string $data , string $method , string $password, bool $raw_output = false, string $iv )

Si $iv Est manquant, un avertissement est émis: "L'utilisation d'un vecteur d'initialisation vide (iv) est potentiellement non sécurisée et déconseillée".

Si $iv Est trop court, un autre avertissement: "IV passé ne fait que 3 octets de long, le chiffrement attend un IV précis de 8 octets, avec un remplissage avec\0"

le même IV doit être utilisé dans openssl_decrypt()

97
espradley

Vous n'avez pas besoin d'un cryptage bidirectionnel - le cryptage sert à maintenir le secret , mais ce que vous cherchez vraiment ici est authenticité .

Les HMAC (essentiellement, les hachages à clé) sont un moyen d'obtenir l'authenticité cryptographique. Accompagnez l'UID avec un HMAC de l'UID (PHP a un implémentation HMAC ), en utilisant une clé que seul le serveur connaît. Au début de chaque demande, vérifiez le HMAC.

Fondamentalement, utilisez le bon outil pour le bon travail.

30
caf

Bien que PHP supporte de nombreux algorithmes de hachage bidirectionnels, je ne pense pas que cela soit utile dans cet exemple. Ce que vous devez faire est:

  1. Chargez la ligne du stockage par l'ID fourni
  2. Vérifiez que le propriétaire de la ligne est l'utilisateur authentifié et sinon lancez une exception et informez l'utilisateur de ne pas recommencer

Mais si votre cœur est déterminé à hacher, choisissez simplement l'un des algorithmes fourni .

3
Miha Hribar

Pour le cryptage bidirectionnel, vérifiez mcrypt , ou si vous préférez une implémentation pure phpseclib .

2
rogeriopvl

Tout d'abord, le cryptage des paramètres d'URL est généralement une mauvaise idée , et une recherche distincte (basée sur une colonne d'index CHAR générée par un CSPRNG) est préférable pour 99,9% des cas d'utilisation.

Cela dit: Oui, vous pouvez utiliser l'extension OpenSSL ( n'utilisez pas mcrypt ) pour crypter les données comme espradley l'a suggéré , cependant je vous préviens de ne pas vous arrêter à simplement le cryptage.

Le chiffrement sans authentification de message est dangereux , surtout si vous faites confiance à une fin- l'utilisateur avec le texte chiffré.

La solution consiste donc à utiliser chiffrement authentifié , qui est facilement accessible avec libsodium, disponible sur PECL .

Si vous ne pouvez pas pour une raison quelconque installer une extension PECL, vous avez le choix entre deux bibliothèques PHP: defuse/php-encryption et zend-crypt . Ils offrent tous deux un cryptage authentifié conforme aux normes et ils sont tous deux sûrs à utiliser (pour ce que ça vaut, j'effectue fréquemment audits de code pour les implémentations de cryptographie en PHP, je ne suis pas simplement une personne aléatoire sur Internet).

0
Scott Arciszewski