Question

  

Comme cette question est plutôt populaire, j'ai jugé utile de la mettre à jour.

     

Permettez-moi de souligner la réponse correcte donnée par AviD à cette question:   

     

Vous ne devez pas stocker de données à chiffrer dans votre cookie. stockez une clé aléatoire de bonne taille (128 bits / 16 octets) dans le cookie et stockez les informations que vous souhaitez protéger. sur le serveur, identifié par la clé du cookie.


Je recherche des informations sur le "meilleur" algorithme de cryptage pour le cryptage des cookies.

J'ai les exigences suivantes:

  • Ça doit être rapide
    le chiffrement et le déchiffrement des données seront effectués pour (presque) chaque demande

  • Il fonctionnera sur de petits ensembles de données, généralement des chaînes d'environ 100 caractères ou moins

  • Il doit être sécurisé, mais ce n'est pas comme si nous sécurisions les transactions bancaires

  • Nous devons être en mesure de déchiffrer les informations afin que SHA1 et autres soient supprimés.

Maintenant, j'ai lu que Blowfish est rapide et sécurisé, et qu'AES est rapide et sécurisé. Avec Blowfish ayant un bloc plus petit.

Je pense que les deux algorithmes offrent une sécurité plus que suffisante? la vitesse deviendrait alors le facteur décisif. Mais je ne sais vraiment pas si ces algorithmes conviennent à une petite chaîne de caractères et s’il existe peut-être un algorithme plus adapté au chiffrement des cookies.

Ma question est donc la suivante:
Quel algorithme de cryptage convient le mieux au cryptage des données de cookie?

Mettre à jour
Pour être plus précis, nous souhaitons chiffrer deux cookies: l’un avec les informations de session et l’autre avec les informations 'me rappeler'.

La plate-forme est PHP en tant que module apache sous Linux sur un VPS.

Mise à jour 2
J'accepte les cletus que le stockage d'informations dans un cookie n'est pas sécurisé.

Cependant, nous devons implémenter une fonctionnalité "rappelez-moi". La méthode acceptée consiste à créer un cookie. Si le client présente ce cookie, il est autorisé à accéder au système avec des droits (presque) égaux, comme s'il présentait la combinaison nom d'utilisateur / mot de passe valide.

Nous souhaitons donc au moins chiffrer toutes les données du cookie pour qu'il:
a) des utilisateurs malveillants ne peuvent pas lire son contenu,
b) Les utilisateurs malveillants ne peuvent pas créer leur propre cookie ou le manipuler.

(Toutes les données des cookies sont nettoyées et leur validité vérifiée avant toute utilisation, mais c'est une autre histoire)

Le cookie de session ne contient plus rien d’identité sessionId / timestamp. Il pourrait probablement être utilisé sans chiffrement, mais je ne vois aucun mal à le chiffrer? (autre que le temps de calcul).

Alors, étant donné que nous devons stocker des données dans un cookie, quel est le meilleur moyen de les chiffrer?

Mise à jour 3
Les réponses à cette question m'ont amené à reconsidérer l'approche choisie. Je peux en effet faire la même chose sans avoir besoin de chiffrement. Au lieu de chiffrer les données, je ne devrais envoyer que des données sans signification sans contexte et impossibles à deviner .

Cependant, je suis aussi désemparé:
Je pensais que le cryptage nous permettait d'envoyer des données dans le BigBadWorld & # 8482 ;, et que nous étions toujours (à peu près) sûrs que personne ne pourrait lire ou altérer le fichier ...
N'était-ce pas le but du cryptage?

Mais les réactions ci-dessous poussent vers: Ne faites pas confiance au cryptage pour réaliser la sécurité.

Qu'est-ce qui me manque ??

Était-ce utile?

La solution

Pas de vraie raison de ne pas utiliser AES avec 256 bits. Assurez-vous de l'utiliser dans le mode CBC et PKCS # 7. rembourrage. Comme vous l'avez dit, rapide et sécurisé.

J'ai lu (non testé) que Blowfish pourrait être légèrement plus rapide ... Cependant, Blowfish présente un inconvénient majeur: son temps de configuration long, ce qui le rendrait mauvais pour votre situation. En outre, AES est plus "éprouvé".

Cela suppose qu'il est vraiment nécessaire de chiffrer symétriquement vos données de cookie. Comme d'autres l'ont fait remarquer, cela ne devrait vraiment pas être nécessaire, et il n'y a que quelques cas extrêmes où il n'y a pas d'autre choix que de le faire. Généralement, il serait préférable de modifier la conception et de revenir à des identifiants de session aléatoires ou, si nécessaire, à des hachages unidirectionnels (à l'aide de SHA-256).
Dans votre cas, à part le signe "normal" identifiant de session aléatoire, votre problème est le "rappelez-vous de moi". fonctionnalité - cela devrait également être mis en œuvre en tant que:

  • un nombre aléatoire long, stocké dans la base de données et mappé sur un compte d'utilisateur;
  • ou un hachage à clé (par exemple, HMAC) contenant par exemple le nom d'utilisateur, horodatage, mebbe un sel, et une clé de serveur secrète. Cela peut bien entendu être vérifié côté serveur ...

On dirait que nous avons un peu perdu le sujet de votre question originale originale et modifié la base de votre question en modifiant la conception ....
Aussi longtemps que nous ferons cela, je recommanderais FORTEMENT CONTRE cette fonctionnalité de persistante "Souviens-toi de moi", pour plusieurs raisons, la plus importante d'entre elles:

  • Il est beaucoup plus probable que quelqu'un vole la clé de rappel de cet utilisateur, ce qui lui permet d'usurper l'identité de l'utilisateur (puis de changer probablement son mot de passe);
  • CSRF - Falsification de requête intersite . Votre fonctionnalité permettra effectivement à un attaquant anonyme de faire en sorte que des utilisateurs non avertis soumettent un message "authentifié". demandes à votre application, même sans être réellement connecté.

Autres conseils

Ceci concerne deux questions distinctes.

Tout d'abord, détournement de session . C’est là qu’un tiers découvre, par exemple, un cookie authentifié et obtient l’accès aux détails de quelqu'un d’autre.

Deuxièmement, il existe une sécurité des données de session . J'entends par là que vous stockez des données dans le cookie (tel que le nom d'utilisateur). Ce n'est pas une bonne idée. De telles données sont fondamentalement non fiables, tout comme les données de formulaire HTML ne le sont pas (quelles que soient la validation Javascript et / ou les restrictions de longueur HTML que vous utilisez, le cas échéant), car un client est libre de soumettre ce qu'il veut.

Vous trouverez souvent des gens (à juste titre) qui préconisent la désinfection des données de formulaire HTML, mais les données de cookie seront acceptées à l'aveuglette. Grosse erreur. En fait, je ne stocke jamais aucune information dans le cookie. Je le considère comme une clé de session et c'est tout.

Si vous souhaitez stocker des données dans un cookie, je vous conseille vivement de réexaminer votre projet.

Le cryptage de ces données ne rend pas l’information plus fiable, car le cryptage symétrique est sujet à une attaque par force brute. Évidemment, l’AES-256 est meilleur que, par exemple, le DES (heh), mais 256 bits de sécurité ne signifient pas nécessairement autant que vous le pensez.

D'une part, les SALT sont généralement générés selon un algorithme ou risquent sinon d'être attaqués.

D'autre part, les données de cookies sont un candidat idéal pour les attaques crib . Si vous savez ou pensez qu'un nom d'utilisateur se trouve dans les données cryptées, votre berceau est là.

Cela nous ramène au premier point: le détournement d’avion.

Il convient de noter que dans les environnements d'hébergement partagé en PHP (à titre d'exemple), vos données de session sont simplement stockées sur le système de fichiers et lisibles par tout le monde sur le même hôte, même s'ils ne savent pas nécessairement sur quel site il se trouve. est pour. Par conséquent, ne stockez jamais les mots de passe en clair, les numéros de carte de crédit, des informations personnelles détaillées ou tout ce qui pourrait être considéré comme sensible dans les données de session dans de tels environnements sans chiffrement ou, mieux encore, simplement en stockant une clé dans la session et en stockant les données sensibles. données dans une base de données.

Remarque: ce qui précède n'est pas propre à PHP.

Mais c'est le chiffrement côté serveur.

Vous pouvez maintenant affirmer que le cryptage d'une session avec des données supplémentaires le rendra plus protégée contre le piratage. Un exemple courant est l'adresse IP de l'utilisateur. Le problème est que beaucoup de gens utilisent le même PC / ordinateur portable à différents endroits (par exemple, points d'accès sans fil Wifi, travail, maison). En outre, de nombreux environnements utiliseront diverses adresses IP comme adresse source, en particulier dans les environnements d'entreprise.

Vous pouvez également utiliser l'agent utilisateur, mais c'est prévisible.

Donc, pour autant que je sache, il n’ya aucune raison réelle d’utiliser le cryptage des cookies. Je n’avais jamais pensé que c’était le cas, mais à la lumière de cette question, j’ai cherché à prouver que c’était bien ou mal. J'ai trouvé quelques discussions sur des personnes suggérant des façons de chiffrer des données de cookies, de le faire de manière transparente avec des modules Apache, etc., mais ces solutions semblaient toutes motivées par la protection des données stockées dans un cookie (ce que vous ne devriez pas faire).

Je n'ai pas encore vu d'argument de sécurité pour chiffrer un cookie qui ne représente rien d'autre qu'une clé de session.

J'aurai volontiers tort de me tromper si quelqu'un peut faire remarquer le contraire.

  

Avertissement de sécurité : ces deux fonctions ne sont pas sécurisées. Ils utilisent le mode BCE et ne parviennent pas à authentifie le texte crypté . Voir cette réponse pour une meilleure façon d'aller de l'avant.

Pour ceux qui lisent et souhaitent utiliser cette méthode dans les scripts PHP. Voici un exemple de travail utilisant Rijndael 256 bits (pas AES).

function encrypt($text, $salt) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text, $salt) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
}

Puis sauvegarder le cookie

setcookie("PHPSESSION", encrypt('thecookiedata', 'longsecretsalt'));

et à lire à la page suivante:

$data = decrypt(
  

Avertissement de sécurité : ces deux fonctions ne sont pas sécurisées. Ils utilisent le mode BCE et ne parviennent pas à authentifie le texte crypté . Voir cette réponse pour une meilleure façon d'aller de l'avant.

Pour ceux qui lisent et souhaitent utiliser cette méthode dans les scripts PHP. Voici un exemple de travail utilisant Rijndael 256 bits (pas AES).

function encrypt($text, $salt) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text, $salt) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
}

Puis sauvegarder le cookie

setcookie("PHPSESSION", encrypt('thecookiedata', 'longsecretsalt'));

et à lire à la page suivante:

<*>COOKIE['PHPSESSION'], 'longsecretsalt');

Vous pouvez obtenir ce que vous voulez en toute sécurité en utilisant AES en mode EAX. Le texte chiffré sera plus grand que le texte en clair; c'est normal pour le cryptage sécurisé.

L’attaquant connaîtra bien sûr la longueur de votre texte en clair à partir du texte chiffré, mais il ne devrait pas être en mesure de déterminer quoi que ce soit d’autre.

Générer des clés AES au hasard.

Assurez-vous d'utiliser un nouveau nonce pour chaque chiffrement et utilisez les "données associées". champ permettant de s’assurer qu’une chose que vous avez chiffrée à une fin donnée n’est pas présentée comme appartenant à une autre (pour que des choses comme le nom d’utilisateur et le nom du cookie puissent y figurer)

  

les réactions ci-dessous poussent vers: Do   ne pas faire confiance au cryptage à accomplir   sécurité.

Plus "Si vous n'êtes pas un expert en cryptage, vous sous-estimerez à quel point il est facile de se tromper". Par exemple, AFAICT personne dans ce fil de discussion n’a abordé les modes d’enchaînement ou l’intégrité des messages, ce qui couvre deux erreurs courantes du débutant.

Cookies rapides cryptés avec Libsodium

Si vous avez besoin de cookies cryptés rapides et sécurisés en PHP, découvrez comment Halite les met en œuvre. Halite s’appuie sur l’extension libsodium PECL pour fournir une cryptographie sécurisée.

<?php
use \ParagonIE\Halite\Cookie;
use \ParagonIE\Halite\Symmetric\Key;
use \ParagonIE\Halite\Symmetric\SecretKey;

// You can also use Key::deriveFromPassword($password, $salt, Key::CRYPTO_SECRETBOX);
$encryption_key = new SecretKey($some_constant_32byte_string_here);

$cookie = new Cookie($encryption_key);

$cookie->store('index', $any_value);
$some_value = $cookie->fetch('other_index');

Si vous ne pouvez pas installer d’extensions PECL, demandez à votre administrateur système ou à votre fournisseur d’hébergement de le faire pour vous. S'ils refusent, vous avez toujours des options.

Cookies cryptés sécurisés en PHP, retenez le sel s'il vous plaît

Les autres réponses vous demandent de chiffrer vos données avec openssl ou mcrypt, mais il leur manque une étape cruciale. Si vous souhaitez chiffrer les données en toute sécurité en PHP , vous devez authentifier vos messages.

Avec l'extension OpenSSL, le processus à suivre se présente comme suit:

Préambule

  • (Avant même de penser au cryptage) Générez une chaîne aléatoire de 128 bits, 192 bits ou 256 bits. Ce sera votre clé principale .

    N'utilisez pas de mot de passe lisible par l'homme. Si, pour une raison quelconque, devez utiliser un mot de passe lisible par l'homme, demandez à Cryptography SE pour obtenir des conseils.

    Si vous avez besoin d'une attention particulière, mon employeur propose des services de conseil en technologie , y compris le développement de la cryptographie. fonctionnalités.

Cryptage

  1. Générez un vecteur d’initialisation (IV) ou un nonce aléatoire. par exemple. random_bytes (openssl_cipher_iv_length ('aes-256-cbc'))
  2. Utilisez HK or un algorithme similaire pour diviser votre clé principale en deux clés:
    1. Une clé de cryptage ( $ eKey )
    2. Une clé d'authentification ( $ aKey )
  3. Cryptez votre chaîne avec openssl_encrypt () avec votre IV et un modate approprié (par exemple, aes-256-ctr ) à l'aide de votre clé de cryptage ( $ eKey ) de l'étape 2.
  4. Calculez une étiquette d'authentification de votre texte chiffré à l'étape 3, à l'aide d'une fonction de hachage à clé telle que HMAC-SHA256. par exemple. hash_hmac ('sha256', $ iv. $ cryptogramme, $ aKey) . Il est très important de s'authentifier après le cryptage et d'encapsuler également l'IV / nonce.
  5. Regroupez la balise d’authentification, IV ou nonce, et le texte chiffré et codez-la éventuellement avec bin2hex () ou base64_encode () . (Avertissement: cette approche pourrait divulguer des informations de synchronisation du cache.)

Déchiffrement

  1. Scindez votre clé en procédant comme indiqué à l'étape 2 du cryptage. Nous avons besoin des deux mêmes clés lors du déchiffrement!
  2. (Décoder et éventuellement) décompressez le MAC, le code IV et le texte chiffré du message condensé.
  3. Vérifiez l'étiquette d'authentification en recalculant le HMAC de l'IV / nonce et le texte chiffré avec le HMAC fourni par l'utilisateur à l'aide de . hash_equals () .
  4. Si et seulement si l'étape 3 est réussie, déchiffrez le texte chiffré à l'aide de $ eKey .

Si vous voulez voir à quoi ça ressemble, voyez cette réponse qui contient un exemple de code .

Si cela semble trop demander, utilisez defuse / php-encryption ou zend-crypt et appelez-le un jour.

Se souvenir de moi des cookies

  

Cependant, nous devons implémenter une fonctionnalité "rappelez-moi". La méthode acceptée consiste à créer un cookie. Si le client présente ce cookie, il est autorisé à accéder au système avec des droits (presque) égaux, comme s'il présentait la combinaison nom d'utilisateur / mot de passe valide.

Le chiffrement n’est en fait pas le bon outil pour ce travail. Vous souhaitez suivre ce processus pour secure se souvenir de moi les cookies en PHP :

Génération d'un jeton Mémoriser mes informations

  1. Générez deux chaînes aléatoires:
    1. Un sélecteur qui sera utilisé pour les recherches dans la base de données. (Le but d'un sélecteur aléatoire au lieu d'un identifiant séquentiel uniquement est de ne pas divulguer le nombre d'utilisateurs actifs sur votre site Web. Si vous ne voulez pas divulguer ces informations, n'hésitez pas à utiliser un identifiant séquentiel. .)
    2. Un validateur qui sera utilisé pour authentifier automatiquement l'utilisateur.
  2. Calcule un hachage de validateur (un simple hachage SHA-256 suffira).
  3. Stockez le sélecteur et le hachage du validateur dans une table de base de données réservée aux connexions automatiques.
  4. Stockez le sélecteur et le validateur dans un cookie sur le client.

Utiliser un jeton "Mémoriser mes informations"

  1. Divisez le cookie entrant en sélecteur et validateur .
  2. Effectuez une recherche dans la base de données (utilisez les instructions préparées !) à l'aide du sélecteur .
  3. Si une ligne est trouvée, calculez le hachage du validateur .
  4. Comparez le hachage calculé à l'étape 3 avec celui stocké dans la base de données, en utilisant à nouveau hash_equals ( ) .
  5. Si l'étape 4 renvoie la valeur true, connectez l'utilisateur au compte approprié.

C’est la stratégie adoptée par Gatekeeper pour l'authentification à long terme des utilisateurs. C'est la solution la plus sécurisée. stratégie proposée à ce jour pour satisfaire à cette exigence.

Bien qu’ils soient très puissants, AES est un standard.

En ce qui concerne la sécurité de petits morceaux de données: le plus petit - le meilleur. Moins les données cryptées sont exposées, plus vous pouvez utiliser la clé. Il y a toujours une limite théorique au nombre de données pouvant être chiffrées dans une clé d'un algorithme donné sans exposer le système à des risques.

Si vous chiffrez le cookie, le serveur doit toujours le déchiffrer pour le lire (pour vérifier la même clé). Par conséquent, tout cookie chiffré est inutile, car s'il est volé (et non modifié), il mènera toujours le pirate vers la droite. à votre compte. C'est aussi dangereux que de ne pas être crypté du tout.

Je pense que le vrai problème de quelqu'un qui vole votre cookie est la connexion entre le serveur et le client. Utilisez la connexion SSL fournie par votre hôte.

En ce qui concerne votre cookie, vous devez créer un identifiant long et aléatoire pour chaque utilisateur de la base de données (faites-le changer à chaque ouverture de session) et définissez-le simplement comme cookie ou session. Le cookie contenant la clé peut être vérifié via php. S'il est égal à un compte ou à une table de votre base de données, exportez les données de la page Web comme d'habitude.

Comme indiqué à plusieurs reprises dans les commentaires précédents, vous devez appliquer la protection de l'intégrité à tout texte chiffré que vous envoyez à l'utilisateur et que vous acceptez de nouveau. Sinon, les données protégées peuvent être modifiées ou la clé de chiffrement récupérée.

En particulier, le monde PHP regorge d'exemples erronés qui l'ignorent (voir cryptographie PHP - procédez avec prudence . ) mais cela s’applique à toutes les langues.

L’un des rares exemples que j’ai vu est PHP-CryptLib qui utilise le cryptage combiné- mode d'authentification pour faire le travail. Pour Python, pyOCB offre des fonctionnalités similaires.

Pourquoi voulez-vous chiffrer le cookie?

Comme je le vois, il y a deux cas: soit vous donnez la clé au client, soit vous ne le faites pas.

Si vous ne donnez pas la clé au client, pourquoi lui donnez-vous les données? Sauf si vous jouez à un jeu bizarre avec un cryptage faible (ce qui n’est pas explicitement votre cas), stockez les données sur le serveur.

Si vous donnez la clé au client, pourquoi la chiffrez-vous en premier lieu? Si vous ne chiffrez pas la communication de la clé, le chiffrement du cookie devient alors inutile: un MITM peut consulter le cookie et vous envoyer le cookie de votre choix. Si vous utilisez un canal chiffré sur le client, pourquoi le surcoût supplémentaire lié au chiffrement des données stockées?

Si vous craignez que d'autres utilisateurs de la machine du client lisent le cookie, abandonnez et supposez que le navigateur définit de bons bits d'autorisation:)

AES (également connu sous le nom de Rijndael) est le plus populaire. La taille de bloc est de 128 bits, ce qui ne représente que 16 octets. Vous parlez d'environ 100 caractères.

Je pense que "donner" & toutes les données même cryptées quand il s'agit de nom d'utilisateur et mot de passe n'est pas bon ... Il y a beaucoup de JS qui peuvent le renifler ... Je vous suggère de créer dans la table des utilisateurs un champ cookie_auth ou autre chose ...

après la première connexion, récupérez: current: navigateur, IP, et votre propre clé de sel, plus votre nom d’hôte var ...

créer un hachage et stocker dans ce champ ... mettre un cookie ... lorsque le cookie " répond " comparez tous ces éléments avec le hachage stocké et terminé ...

même si quelqu'un " vole " un cookie, ils ne pourront pas l'utiliser: -)

J'espère que cela vous aidera: -)

feha vision.to

De plus, j'ai essayé le mcrypt_encrypt et gardez une chose à l'esprit. Si vous utilisez base64_encode (mcrypt_encrypt (...)) .

et plus tard, vous faites base64_decode et vous sortez les données cryptées ( echo ). Vous serez probablement foutu et ne rien voir. Toutefois, si vous utilisez mcrypt_decrypt (... base64_decode ($ value)) . Vous verrez les données d'origine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top