Étant donné que cette question est plutôt populaire, j'ai pensé qu'il était utile de lui donner une mise à jour.
Permettez-moi de souligner la bonne réponse donnée par AviD à cette question:
Vous ne devez pas stocker de données à chiffrer dans votre cookie. Au lieu de cela, stockez une clé aléatoire de bonne taille (128 bits/16 octets) dans le cookie et stocker les informations que vous souhaitez sécuriser sur le serveur, identifiées 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
Cela doit être sécurisé, mais ce n'est pas comme si nous sécurisions les transactions bancaires
Nous devons être en mesure de décrypter les informations afin que SHA1 et autres soient sortis.
Maintenant, j'ai lu que Blowfish est rapide et sécurisé, et j'ai lu que AES est rapide et sécurisé. Avec Blowfish ayant une taille de bloc plus petite.
Je pense que les deux algorithmes offrent une sécurité plus qu'adéquate? la vitesse deviendrait alors le facteur décisif. Mais je n'ai vraiment aucune idée si ces algorithmes sont adaptés à une petite chaîne de caractères et s'il existe peut-être un algorithme mieux adapté au chiffrement des cookies.
Donc ma question est:
Quel algorithme de cryptage est le meilleur pour crypter les données des cookies?
Mise à jour
Pour être plus précis, nous voulons crypter 2 cookies: l'un avec les informations de session et l'autre avec les informations "me souvenir".
La plateforme est PHP comme module Apache sous Linux sur un VPS.
Mise à jour 2
Je suis d'accord avec cletus que le stockage de toute information dans un cookie n'est pas sécurisé.
Cependant, nous avons besoin d'implémenter une fonction "me souvenir". La manière acceptée de procéder consiste à définir 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 de mot de passe de nom d'utilisateur valide.
Nous voulons donc au moins crypter toutes les données du cookie pour qu'il:
a) les utilisateurs malveillants ne peuvent pas lire son contenu,
b) les utilisateurs malveillants ne peuvent pas fabriquer leur propre cookie ou le falsifier.
(Toutes les données des cookies sont nettoyées et vérifiées pour leur validité avant d'en faire quoi que ce soit, mais c'est une autre histoire)
Le cookie de session ne contient rien de sessionId/timestamp. Il pourrait probablement être utilisé sans chiffrement, mais je ne vois aucun mal à le chiffrer? (autre que le temps de calcul).
Donc, étant donné que nous devons stocker des données dans un cookie, quelle est la meilleure façon de les crypter?
Mise à jour 3
Les réponses à cette question m'ont fait reconsidérer l'approche choisie. Je peux en effet faire de même sans avoir besoin de chiffrement. Au lieu de crypter les données, je ne devrais envoyer que des données qui n'ont aucun sens sans leur contexte et ne peuvent pas être devinés.
Cependant, je suis aussi perdu:
Je pensais que le chiffrement nous permettait d'envoyer des données vers le BigBadWorld ™, tout en étant (assez) sûr que personne ne pouvait le lire ou le falsifier ...
N'était-ce pas là tout l'intérêt du chiffrement?
Mais les réactions ci-dessous Poussent vers: Ne faites pas confiance au chiffrement pour assurer la sécurité.
Qu'est-ce qui me manque ??
Aucune vraie raison de ne pas aller avec AES avec 256 bits. Assurez-vous de l'utiliser dans mode CBC et dans le remplissage PKCS # 7. Comme vous l'avez dit, rapide et sécurisé.
J'ai lu (non testé) que Blowfish peut être légèrement plus rapide ... Cependant Blowfish a un inconvénient majeur de long temps d'installation, ce qui rendrait la situation mauvaise. De plus, l'AES est plus "éprouvé".
Cela suppose qu'il est vraiment nécessaire pour crypter symétriquement vos données de cookies. Comme d'autres l'ont noté, cela ne devrait vraiment pas être nécessaire, et il n'y a que quelques cas Edge où il n'y a pas d'autre choix que de le faire. Généralement, il vous conviendrait mieux de modifier la conception et de revenir à des identificateurs de session aléatoires ou, si nécessaire, à des hachages unidirectionnels (à l'aide de SHA-256).
Dans votre cas, en plus de l'identifiant de session aléatoire "normal", votre problème est la fonctionnalité "se souvenir de moi" - cela devrait également être implémenté comme suit:
On dirait que nous avons un peu dépassé le sujet de votre question spécifique originale - et changé la base de votre question en changeant la conception ...
Donc tant que nous faisons cela, je recommanderais FORTEMENT [~ # ~] contre [~ # ~] ce caractéristique de "se souvenir de moi" persistant, pour plusieurs raisons, la plus importante d'entre elles:
Cela touche deux questions distinctes.
Tout d'abord, détournement de session . C'est là qu'un tiers découvre, par exemple, un cookie authentifié et accède aux détails de quelqu'un d'autre.
Deuxièmement, il existe la sécurité des données de session . J'entends par là que vous stockez des données dans le cookie (comme le nom d'utilisateur). Ce n'est pas une bonne idée. Ces données sont fondamentalement non fiables, tout comme les données de formulaire HTML ne sont pas fiables (quelles que soient les restrictions de validation Javascript et/ou 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) prônant la désinfection des données des formulaires HTML, mais les données des cookies seront acceptées aveuglément sur leur valeur nominale. Grosse erreur. En fait, je ne stocke jamais d'informations dans le cookie. Je le vois comme une clé de session et c'est tout.
Si vous avez l'intention de stocker des données dans un cookie, je vous conseille fortement de reconsidérer.
Le chiffrement de ces données ne rend pas les informations plus fiables car le chiffrement symétrique est susceptible d'être attaqué par force brute. Évidemment, AES-256 est meilleur que, par exemple, 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 sont autrement susceptibles d'être attaqués.
D'autre part, les données de cookies sont un candidat idéal pour les attaques crèche . S'il est connu ou soupçonné qu'un nom d'utilisateur figure dans les données cryptées, il y a votre berceau.
Cela nous ramène au premier point: le détournement.
Il convient de noter que sur les environnements d'hébergement partagé dans PHP (à titre d'exemple), vos données de session sont simplement stockées sur le système de fichiers et sont lisibles par n'importe qui d'autre sur ce même hôte bien qu'ils ne le fassent pas '' Je ne sais pas nécessairement à quel site il est destiné. Ne stockez donc jamais des mots de passe en clair, des numéros de carte de crédit, des informations personnelles détaillées ou tout ce qui pourrait autrement être considéré comme sensible dans les données de session dans de tels environnements sans aucune forme de cryptage ou, mieux encore, simplement en stockant un clé dans la session et le stockage des données sensibles réelles dans une base de données.
Remarque: ce qui précède n'est pas unique à PHP.
Mais c'est le chiffrement côté serveur.
Maintenant, vous pourriez faire valoir que le cryptage d'une session avec des données supplémentaires le rendra plus sûr contre le piratage. Un exemple courant est l'adresse IP de l'utilisateur. Le problème est que de nombreuses personnes utilisent le même PC/ordinateur portable à de nombreux endroits différents (par exemple, les points d'accès Wi-Fi, le travail, la maison). De nombreux environnements utilisent également une variété d'adresses IP comme adresse source, en particulier dans les environnements d'entreprise.
Vous pouvez également utiliser l'agent utilisateur, mais c'est concevable.
Donc, pour autant que je sache, il n'y a aucune raison réelle d'utiliser le cryptage des cookies. Je n'ai jamais pensé qu'il y en avait, mais à la lumière de cette question, j'ai cherché à prouver que c'était vrai ou faux. J'ai trouvé quelques discussions sur des personnes suggérant des moyens de crypter les données des cookies, de le faire de manière transparente avec les modules Apache, etc., mais tout cela semblait motivé par la protection des données stockées dans un cookie (ce que je ne devrais pas faire).
Je n'ai pas encore vu d'argument de sécurité pour crypter un cookie qui ne représente rien de plus qu'une clé de session.
Je serai heureux de me tromper si quelqu'un peut signaler le contraire.
Avertissement de sécurité : Ces deux fonctions ne sont pas sécurisées. Ils utilisent mode ECB et ne parviennent pas à authentifier le texte chiffré . Voir cette réponse pour une meilleure marche à suivre.
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)));
}
Ensuite, pour enregistrer le cookie
setcookie("PHPSESSION", encrypt('thecookiedata', 'longsecretsalt'));
et à lire sur la page suivante:
$data = decrypt($_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 un 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érez des clés AES de manière aléatoire.
Assurez-vous d'utiliser un nouveau nonce pour chaque chiffrement et utilisez le champ "données associées" pour vous assurer qu'une chose que vous avez chiffrée dans un but n'est pas présentée comme étant pour une autre (afin que des choses comme le nom d'utilisateur et le nom du cookie puissent entrer Là)
les réactions ci-dessous Poussez vers: Ne faites pas confiance au chiffrement pour assurer la sécurité.
Plus "si vous n'êtes pas un expert en chiffrement, vous sous-estimerez à quel point il est facile de se tromper". Par exemple, AFAICT personne d'autre dans ce fil n'a discuté des modes de chaînage ou de l'intégrité des messages, qui couvre deux erreurs courantes des débutants.
Si vous avez besoin de cookies cryptés rapides et sécurisés en PHP, découvrez comment Halite les implémente. 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 hébergeur de le faire pour vous. S'ils refusent, vous avez encore des options.
Les autres réponses vous demandent de crypter vos données avec openssl ou mcrypt, mais il leur manque une étape cruciale. Si vous voulez crypter en toute sécurité les données en PHP , vous devez authentifier vos messages.
En utilisant l'extension OpenSSL, le processus que vous devez suivre ressemble à ceci:
(Avant même de penser au chiffrement) 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 vous, pour une raison quelconque, doit utilisez 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 services de conseil technologique , y compris le développement de fonctionnalités de cryptographie.
random_bytes(openssl_cipher_iv_length('aes-256-cbc'))
$eKey
)$aKey
)openssl_encrypt()
avec votre IV et un modate approprié (par exemple aes-256-ctr
) En utilisant votre clé de chiffrement ($eKey
) À partir de l'étape 2.hash_hmac('sha256', $iv.$ciphertext, $aKey)
. Il est très important de s'authentifier après le cryptage et d'encapsuler également l'IV/nonce. bin2hex()
ou base64_encode()
. (Avertissement: cette approche pourrait fuite d'informations de synchronisation du cache.)hash_equals()
.$eKey
.Si vous voulez voir à quoi tout cela ressemble, voyez cette réponse qui a un exemple de code .
Si cela vous semble trop de travail, utilisez defuse/php-encryption ou zend-crypt et appelez-le un jour.
Cependant, nous avons besoin d'implémenter une fonction "me souvenir". La manière acceptée de procéder consiste à définir 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 de mot de passe de nom d'utilisateur valide.
Le chiffrement n'est en fait pas l'outil approprié pour ce travail. Vous voulez suivre ce processus pour se souvenir des cookies sécurisés en PHP :
selector
qui sera utilisé pour les recherches de base de données. (Le but d'un sélecteur aléatoire au lieu d'un simple ID séquentiel est de pas divulguer le nombre d'utilisateurs actifs sur votre site Web. Si vous êtes à l'aise de divulguer ces informations, n'hésitez pas à utiliser simplement un ID séquentiel.)validator
qui sera utilisé pour authentifier automatiquement l'utilisateur.validator
(un simple hachage SHA-256 suffira).selector
et le hachage du validator
dans une table de base de données réservée aux connexions automatiques.selector
et validator
dans un cookie sur le client.selector
et validator
.selector
.validator
.hash_equals()
.C'est la stratégie que Gatekeeper a adoptée pour l'authentification à long terme des utilisateurs et c'est la stratégie la plus sûre proposée à ce jour pour satisfaire cette exigence.
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. 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 de mauvais exemples qui l'ignorent (voir Cryptographie PHP - procédez avec précaution ) mais cela s'applique à n'importe quel langage.
L'un des rares bons exemples que j'ai vus est PHP-CryptLib qui utilise le mode de cryptage-authentification combiné pour faire le travail. Pour Python pyOCB offre des fonctionnalités similaires.
Bien que tous deux très forts, AES est un standard.
En ce qui concerne la sécurité des petits morceaux de données: le plus petit - le mieux. Moins les données chiffrées sont exposées, plus vous pouvez utiliser la clé longtemps. Il y a toujours une limite théorique de la quantité de données pouvant être chiffrées dans une clé d'un algorithme donné sans exposer le système à des risques.
Si vous cryptez le cookie, le serveur doit encore le décoder pour le lire (pour vérifier la même clé), donc tout cookie crypté est inutile, car s'il est volé (et non modifié), il mènera toujours le pirate directement sur votre compte . C'est tout aussi dangereux que non chiffré du tout.
Je crois 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.
Quant à votre cookie, vous devez créer un long identifiant aléatoire par utilisateur dans la base de données (le faire changer à chaque connexion) et le définir comme cookie ou session. Le cookie qui contient la clé peut être vérifié via php et s'il est égal à un compte ou une table dans votre base de données, videz les données sur la page Web comme d'habitude.
Pourquoi voulez-vous crypter le cookie?
Selon moi, 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, alors pourquoi lui donnez-vous les données? À moins que vous ne jouiez à un jeu étrange avec un cryptage faible (ce que vous n'êtes pas explicitement), vous pourriez aussi bien stocker les données sur le serveur.
Si vous faites donnez la clé au client, alors pourquoi la cryptez-vous en premier lieu? Si vous ne cryptez pas la communication de la clé, alors le cryptage du cookie est théorique: un MITM peut regarder le cookie et vous envoyer tout cookie qu'il souhaite. Si vous utilisez un canal crypté vers le client, pourquoi les frais supplémentaires de cryptage 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 :)
De plus, j'ai essayé le mcrypt_encrypt
Et une chose s'il vous plaît gardez à l'esprit. Si vous faites base64_encode(mcrypt_encrypt(...))
.
et plus tard, vous faites base64_decode
et sortez les données chiffrées (echo
). Vous serez probablement foutu et ne verrez rien. Cependant, si vous faites mcrypt_decrypt( ... base64_decode($value) )
. Vous verrez les données d'origine.
Je pense que "donner" des données même cryptées quand il s'agit de nom d'utilisateur et de 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 DB des utilisateurs un champ cookie_auth ou autre .. .
après la première connexion, rassemblez: actuel: navigateur, IP, et votre propre clé sel, plus votre nom d'hôte var ...
créer un hachage et stocker dans ce champ ... définir un cookie ... lorsque le cookie "répond" comparer tout cela avec le hachage stocké et fait ...
même si quelqu'un "vole" un cookie, il ne pourra pas l'utiliser :-)
J'espère que cela t'aides :-)
feha vision.to
L'AES (également connu sous le nom de Rijndael) est le plus populaire. La taille de bloc est de 128 bits, ce qui n'est que de 16 octets, et vous parlez "environ 100 caractères".