Les deux sens de chiffrement: j'ai besoin de stocker des mots de passe qui peuvent être récupérés
Je suis entrain de créer une application qui permettra de stocker les mots de passe, que l'utilisateur peut récupérer et voir. Les mots de passe d'un périphérique matériel, donc la vérification contre les hachages sont hors de question.
Ce que j'ai besoin de savoir, c'est:
-
Comment chiffrer et de déchiffrer un mot de passe en PHP?
-
Ce qui est le plus sûr de l'algorithme pour chiffrer les mots de passe avec?
-
Où puis-je stocker la clé privée?
-
Au lieu de stocker la clé privée, est-ce une bonne idée de demander aux utilisateurs d'entrer la clé privée de tout temps, ils ont besoin d'un mot de passe décrypté? (Les utilisateurs de cette application peuvent être de confiance)
-
De quelles manières le mot de passe volés et de les déchiffrer? Que dois-je faire attention?
- Remarque: Libsodium est maintenant compilé dans le coeur de PHP pour >= 7.2. Ce serait le "aller à" solution maintenant que c'est plein de méthodes modernes, à la différence de mcrypt qui est considéré comme obsolète et a été supprimé.
Vous devez vous connecter pour publier un commentaire.
Personnellement, je voudrais utiliser
mcrypt
comme les autres affiché. Mais il ya beaucoup plus à la note...Comment chiffrer et de déchiffrer un mot de passe en PHP?
Voir ci-dessous pour une forte classe qui prend soin de tout pour vous:
Ce qui est le plus sûr de l'algorithme pour chiffrer les mots de passe avec?
la plus sûre? l'un d'eux. La méthode la plus sûre si vous allez à chiffrer est de protéger contre la divulgation d'informations vulnérabilités XSS, à distance de l'inclusion, etc). Si elle sort, l'attaquant peut éventuellement se fissurer le chiffrement (pas de chiffrement est de 100% de l'onu-réversible sans la clé Comme @NullUserException points ce n'est pas tout à fait vrai. Il y a quelques systèmes de cryptage qui sont impossible à décrypter comme OneTimePad).
Où puis-je stocker la clé privée?
Ce que je voudrais faire est d'utiliser 3 touches. L'un est fourni par l'utilisateur, l'une est spécifique à l'application et l'autre est spécifique à l'utilisateur (comme le sel). L'application spécifique de la clé peut être stocké n'importe où (dans un fichier de config à l'extérieur de la web-racine, dans une variable d'environnement, etc). L'utilisateur spécifique serait stockée dans une colonne dans la db suivante pour le mot de passe crypté. L'utilisateur fournies ne seraient pas stockées. Alors, vous feriez quelque chose comme ceci:
L'avantage, c'est que toutes les 2 des clés peut être compromise, sans compromettre les données. Si il y a une attaque par Injection SQL, ils peuvent obtenir de la
$userKey
, mais pas les 2 autres. Si il y a un serveur local exploiter, ils peuvent obtenir$userKey
et$serverKey
, mais pas le troisième$userSuppliedKey
. Si ils vont battre l'utilisateur avec une clé, ils peuvent obtenir de la$userSuppliedKey
, mais pas les 2 autres (mais là encore, si l'utilisateur est battu avec une clé, vous êtes trop tard de toute façon).Au lieu de stocker la clé privée, est-ce une bonne idée de demander aux utilisateurs d'entrer la clé privée de tout temps, ils ont besoin d'un mot de passe décrypté? (Les utilisateurs de cette application peuvent être de confiance)
Absolument. En fait, c'est la seule façon que je le ferais. Sinon, vous auriez besoin de stocker une version non chiffrée dans une semelle format de stockage (mémoire partagée, telles que APC ou memcached, ou dans un fichier de session). C'est vous exposer à d'autres compromis. Ne jamais stocker de la version non chiffrée du mot de passe à tout, sauf à une variable locale.
De quelles manières le mot de passe volés et de les déchiffrer? Que dois-je faire attention?
Toute forme de compromis de vos systèmes de laisser afficher des données chiffrées. Si ils peuvent injecter du code ou obtenez à votre système de fichiers, ils peuvent consulter les données déchiffrées (car ils peuvent modifier les fichiers de déchiffrer les données). Toute forme de Relecture ou d'attaque de type MITM sera également leur donner un accès complet à l'clés impliquées. Flairant le raw HTTP trafic sera également leur donner les clés.
De l'utilisation de SSL pour l'ensemble du trafic. Et assurez-vous que rien sur le serveur a tout type de vulnérabilités (CSRF, XSS, SQL Injection, augmentation de Privilège, Exécution de Code à Distance, etc).
Edit: Voici une classe PHP de la mise en œuvre d'une solide méthode de chiffrement:
Remarque que je suis en utilisant une fonction ajoutée dans PHP 5.6:
hash_equals
. Si vous êtes en baisse de 5,6, vous pouvez utiliser ce substitut de la fonction qui implémente un calendrier-sûr de comparaison fonction à l'aide de double HMAC vérification:Utilisation:
Puis, à décrypter:
Notez que j'ai utilisé
$e2
le deuxième temps de vous montrer les différentes instances seront toujours correctement déchiffrer les données.Maintenant, comment ça fonctionne et pourquoi l'utiliser sur une autre solution:
Clés
Les touches ne sont pas directement utilisées. Au lieu de cela, la clé est tendu par une norme PBKDF2 dérivation.
La clé utilisée pour le chiffrement est unique pour chaque bloc de texte chiffré. La clé fournie devient donc un "master key". Cette classe fournit donc une rotation de la clé de chiffrement et d'authentification des clés.
REMARQUE IMPORTANTE, le
$rounds
paramètre est configuré pour vrai des touches au hasard d'une force suffisante (128 bits de sécurité Cryptographique aléatoire au minimum). Si vous allez utiliser un mot de passe, ou de la non-clé aléatoire (ou moins aléatoire puis 128 bits de CS aléatoire), vous doit augmentation de ce paramètre. Je vous suggère un minimum de 10000 mots de passe (le plus que vous pouvez vous permettre, le mieux, mais il va ajouter à l'exécution)...L'Intégrité Des Données
De chiffrement:
MCRYPT_BLOWFISH
ouMCRYPT_RIJNDAEL_128
méthode de chiffrement etMCRYPT_MODE_CBC
pour la mode. Elle est assez forte, et encore assez rapide (un de chiffrement et de déchiffrement cycle dure environ 1/2 seconde sur ma machine).Maintenant, comme pour le point 3, à partir de la liste, ce qui vous donnerait une fonction comme ceci:
Vous pourrait étirer dans le
makeKey()
fonction, mais depuis ça va être tendu plus tard, il n'y a pas vraiment un énorme point de le faire.Autant que la taille de stockage, il dépend de la forme de texte brut. Blowfish utilise un 8 octets de taille de bloc, de sorte que vous aurez:
Donc, pour un 16 caractère de source de données, il y aura 16 caractères de données chiffrées. Cela signifie donc que le réel des données chiffrées de la taille est de 16 octets, en raison de rembourrage. Puis ajouter les 16 octets pour le sel et 64 octets pour le hmac et le total stocké taille est de 96 octets. Il y a donc, au mieux, un de 80 caractères généraux, et, au pire, 87 caractère de frais généraux...
J'espère que ça aide...
Remarque: 12/11/12: je viens de mettre à jour cette classe avec une BIEN meilleure méthode de cryptage, en utilisant mieux les clés dérivées, et la fixation de la MAC génération...
$dec = mcrypt_...
est$data = $this->unpad($data);
. Si vous modifiez pour$data = $this->unpad($dec);
il semble fonctionner pour moi-64
s à-128
aidé (de sorte que vous obtenez$enc = substr($data, 128, -128)
et$mac = substr($data, -128);
hash_hmac
pour en faire un hachage binaire (il était hex, ce qui double l'espace de stockage). Donc, avec la modification, il faut supprimer la nécessité de mettre à jour ces valeurs...bin2hex
avant de l'insérer, puishex2bin
avant de déchiffrer, mais je n'ai pas été en mesure de décrypter de manière fiable. Toutes les suggestions?Comment chiffrer et de déchiffrer un mot de passe en PHP?
Par la mise en œuvre de l'un des nombreux algorithmes de chiffrement. (ou en utilisant l'une des nombreuses bibliothèques)
Ce qui est le plus sûr de l'algorithme pour chiffrer les mots de passe avec?
Il ya des tonnes de différents algorithmes, dont aucun n'est fiable à 100%. Mais beaucoup d'entre eux sont assez sécurisé pour le commerce et même à des fins militaires
Où puis-je stocker la clé privée?
Si vous avez décidé de mettre en œuvre la clé publique - algorithme de chiffrement(RSA par exemple), vous n'avez pas stocker la clé privée. utilisateur de la clé privée. votre système dispose de la clé publique qui pourrait être stocké n'importe où vous le souhaitez.
Au lieu de stocker la clé privée, est-ce une bonne idée de demander aux utilisateurs d'entrer la clé privée de tout temps, ils ont besoin d'un mot de passe décrypté? (Les utilisateurs de cette application peuvent être de confiance)
Eh bien, si votre utilisateur peut rappeler ridiculement long nombres premiers, alors oui, pourquoi pas. Mais généralement vous aurez besoin de venir avec le système qui permettra aux utilisateurs de stocker leur clé quelque part.
De quelles manières le mot de passe volés et de les déchiffrer? Que dois-je faire attention?
Cela dépend de l'algorithme utilisé. Cependant, assurez-vous toujours que vous n'envoyez pas de mot de passe non crypté ou de l'utilisateur. Soit de chiffrer/déchiffrer sur le côté client, ou de l'utilisation du protocole https(ou l'utilisateur d'autres moyens cryptographiques pour sécuriser la connexion entre le serveur et le client).
Toutefois, si vous avez besoin de stocker des mots de passe chiffrés de façon, je vous suggère d'utiliser un simple XOR de Chiffrement. Le principal problème de cet algorithme est qu'il peut être facilement brisée par l'analyse de la fréquence. Cependant, comme, en général, les mots de passe ne sont pas fabriqués à partir de longs paragraphes de texte en anglais, je ne pense pas que vous devriez vous inquiéter à ce sujet. Le deuxième problème avec Chiffrement XOR est que si vous avez un message chiffré et déchiffré forme vous pourriez facilement trouver le mot de passe avec lequel il a été chiffré. Encore, pas un gros problème dans votre cas, tant que cela ne touche que l'utilisateur qui a déjà été compromise par d'autres moyens.
L'exemple le manuel est légèrement modifié pour cet exemple):
Vous utilisez mcrypt_decrypt pour décrypter votre mot de passe.
Le meilleur algorithme est plutôt subjectif - demander à 5 personnes, obtenez 5 réponses. Personnellement, si la valeur par défaut (Blowfish) n'est pas assez bon pour vous, vous avez probablement plus de problèmes!
Étant donné qu'il est nécessaire par PHP pour chiffrer - pas sûr que vous pouvez cacher n'importe où - recevoir des commentaires sur cette. Standard de PHP meilleures pratiques de codage s'applique bien sûr!
Étant donné que la clé de chiffrement sera dans votre code, de toute façon, pas sûr de ce que vous gagnerez, en fournissant le reste de votre application est sécurisée.
Évidemment, si le mot de passe chiffré et la clé de chiffrement sont volés, puis game over.
Je l'avais mis un coureur sur ma réponse - je ne suis pas un PHP crypto expert, mais je pense que ce que j'ai répondu à la pratique courante - je recevoir des commentaires d'autres peuvent avoir.
$pass = $text
. Je pense qu'il a changé, que pour répondre à la question, et n'a pas remarqué la deuxième occurrence.MCRYPT_MODE_ECB
ne pas utiliser un IV. Deuxièmement, si c'était le cas, vous auriez besoin de stocker le IV que vous ne pouvez pas déchiffrer les données sans elle...Beaucoup d'utilisateurs ont suggéré l'utilisation d'mcrypt... ce qui est correct, mais je voudrais aller un peu plus loin afin de le rendre facilement stockées et transférées (comme parfois des valeurs chiffrées peut la rendre difficile à envoyer à l'aide d'autres technologies comme curl, ou json).
Après avoir été chiffrés à l'aide de mcrypt, le lancer à travers base64_encode puis de le convertir en code hexadécimal. Une fois dans le code hex il est facile de transférer dans une variété de façons.
Et de l'autre côté:
Je voudrais seulement suggérer chiffrement à clé publique si vous souhaitez la possibilité de définir un mot de passe utilisateur sans leur interaction (ce qui peut être pratique pour se réinitialise et partagé leurs mots de passe).
Clé publique
openssl_public_encrypt
etopenssl_private_decrypt
Symétrique
Les deux
4
. Oui - les utilisateurs doivent entrer leur mot de passe d'application à chaque fois, mais de les stocker dans la session soulever d'autres questions5
.openssl_private_decrypt()
.J'ai essayé quelque chose comme ça, mais veuillez noter que je ne suis pas cryptographe, ni moi, détenir une connaissance approfondie des
php
ou de tout langage de programmation. C'est juste une idée. Mon idée est de stocker de l'key
dans un certain fichier oudatabase
(ou entrez manuellement) qui(emplacement) ne peut pas être facilement prévisible(Et bien sûr, tout sera décrypté un jour, le concept est d'allonger le moment du déchiffrement) et de chiffrer les informations sensibles.Veuillez noter qu'il est juste un concept. Toute amélioration dans ce code serait très appréciable.
Hein? Je ne comprends pas. Avez-vous tout simplement dire que le mot de passe doit être récupérable?
Comme d'autres l'ont dit, l'extension mcrypt donne accès à de nombreuses fonctions cryptographiques - cependant, vous êtes en invitant les utilisateurs à mettre tous leurs œufs dans le même panier, qui sera potentiellement être une cible pour les pirates - et si vous ne savez même pas comment commencer à résoudre le problème, alors vous faites à vos utilisateurs un mauvais service. Vous n'êtes pas en mesure de comprendre comment protéger les données.
Plupart des failles de sécurité viennent pas parce que l'algorithme sous-jacent est défectueux ou mal -, mais en raison de problèmes avec la façon dont l'algorithme est utilisé dans le code de l'application.
Cela dit, il est possible de construire un système raisonnablement sécurisé.
Vous ne devez envisager un chiffrement asymétrique si vous avez une exigence pour un utilisateur de créer un message sécurisé qui est lisible par un autre (spécifique) de l'utilisateur. La raison en est que son gourmand en ressources. Si vous souhaitez simplement fournir un référentiel pour les utilisateurs d'entrer et de récupérer leurs propres données, le chiffrement symétrique est adéquate.
Si, toutefois, vous pouvez stocker la clé pour déchiffrer le message au même endroit que le message chiffré (ou lorsque le message chiffré est stocké), alors le système n'est pas sécurisé. Utiliser le même jeton d'authentification pour l'authentification de l'utilisateur comme pour la clé de déchiffrement (ou, dans le cas de chiffrement assymétrique, utilisez le jeton comme la clé privée phrase de passe). Puisque vous aurez besoin de stocker le jeton sur le serveur où le déchiffrement se fait au moins temporairement, vous pouvez envisager d'utiliser un non-consultable session de stockage de substrat, ou en passant directement le jeton à un démon associé à la session qui serait de stocker le jeton dans la mémoire et effectuer le déchiffrement des messages sur demande.
Utilisation password_hash et password_verify
Et à déchiffrer: