La meilleure façon d'utiliser PHP pour chiffrer et déchiffrer les mots de passe? [dupliquer]

StackOverflow https://stackoverflow.com/questions/1289061

Question

  

Possible en double:    PHP cryptage 2 voies: Je dois stocker les mots de passe qui peuvent être récupérés

Je prévois de stocker des informations de compte à l'étranger pour mes utilisateurs sur mon site, alias le nom d'utilisateur et mots de passe rapidshare, etc ... Je veux garder l'information sécuritaire, mais je sais que si je Hash leurs informations, je ne peux pas le récupérer pour une utilisation ultérieure.

base64 est en mesure de déchiffrer-donc il n'y a pas de point à l'aide que tout simplement hors tension. Mon idée est de brouiller l'utilisateur et de passer avant et après se base64ed de cette façon, même après le déchiffrer, vous obtenez une drôle texte regardant si vous essayez de décrypter. Y at-il une fonction php qui accepte les valeurs qui feront une bousculade unique d'une chaîne et désembrouiller plus tard lorsque la valeur est reinputed?

Toutes les suggestions?

Était-ce utile?

La solution

Vous ne devriez pas chiffrer les mots de passe, plutôt que vous devez les hachage en utilisant un algorithme comme bcrypt. Cette réponse explique comment implémenter correctement le mot de passe de hachage en PHP . Pourtant, voici comment vous crypter / décrypter :

$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces

Pour Crypter:

$iv = mcrypt_create_iv(
    mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
    MCRYPT_DEV_URANDOM
);

$encrypted = base64_encode(
    $iv .
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        $string,
        MCRYPT_MODE_CBC,
        $iv
    )
);

Pour Décrypter:

$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

$decrypted = rtrim(
    mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
        MCRYPT_MODE_CBC,
        $iv
    ),
    "\0"
);

Avertissement : L'exemple ci-dessus cryptent les informations, mais il n'authentifie pas le cryptogramme pour empêcher toute manipulation. Vous devez pas appuyer sur le cryptage non authentifié la sécurité , d'autant plus que le code prévu est vulnérable aux attaques d'oracle de remplissage.

Voir aussi:

En outre, ne pas simplement utiliser un « mot de passe » pour une clé de chiffrement. Les clés de chiffrement sont des chaînes aléatoires.


Démo à 3v4l.org :

echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "

Autres conseils

  

Avertissement de sécurité : Cette classe est pas sûr. Il utilise Rijndael256-BCE, ce qui est sémantiquement sûr. Tout simplement parce que « ça marche » ne veut pas dire « il est sûr ». , Il déshabille aussi tailing espaces par la suite en raison de ne pas utiliser un rembourrage approprié.

Trouvé cette classe récemment, il fonctionne comme un rêve!

class Encryption {
    var $skey = "yourSecretKey"; // you can change it

    public  function safe_b64encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }

    public function safe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public  function encode($value){ 
        if(!$value){return false;}
        $text = $value;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
        return trim($this->safe_b64encode($crypttext)); 
    }

    public function decode($value){
        if(!$value){return false;}
        $crypttext = $this->safe_b64decode($value); 
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
        return trim($decrypttext);
    }
}

Et pour l'appeler:

$str = "My secret String";

$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);    

echo "$encoded<p>$decoded";
  

Avertissement de sécurité:. Ce code est pas sécurisé

exemple de travail

define('SALT', 'whateveryouwant'); 

function encrypt($text) 
{ 
    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) 
{ 
    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))); 
} 

$encryptedmessage = encrypt("your message"); 
echo decrypt($encryptedmessage); 

Une chose que vous devriez être très au courant lorsque l'on traite avec un cryptage:

Essayer d'être intelligent et d'inventer votre propre chose sera généralement vous laisser avec quelque chose d'insécurité.

Vous seriez probablement mieux loti en utilisant l'une des extensions de cryptographie qui viennent avec PHP.

Cela ne vous donnera la protection marginale. Si l'attaquant peut exécuter du code arbitraire dans votre application, ils peuvent obtenir les mots de passe exactement de la même façon que votre application peut. Vous pouvez toujours obtenir une certaine protection contre des attaques par injection SQL et des sauvegardes db égarées si vous stockez une clé secrète dans un fichier et l'utiliser pour chiffrer sur le chemin de la DB et décrypter à la sortie. Mais vous devez utiliser bindparams pour éviter complètement la question de l'injection SQL.

Si décider de chiffrer, vous devez utiliser une bibliothèque Crypto de haut niveau pour cela, ou vous se tromper. Vous devrez obtenir la clé-setup, contrôle de remplissage des messages et l'intégrité correcte, ou tous vos efforts de cryptage est de peu d'utilité. GPGME est un bon choix pour un exemple. Mcrypt est trop faible et vous obtiendrez probablement mal.

  

Securiy Avertissement : Ce code est insécurité . En plus d'être vulnérables aux attaques-cryptogramme choisi, sa dépendance à l'égard unserialize() rend vulnérable à l'injection PHP objet.

Pour gérer une chaîne / tableau j'utilise ces deux fonctions:

function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
 return $s;
}

function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
 return $s;
}

Il est souple comme vous pouvez stocker / envoyer via l'URL d'une chaîne ou un tableau parce que la chaîne / tableau est serialzed avant le cryptage.

Consultez mycrypt (): http://us.php.net /manual/en/book.mcrypt.php

Et si vous utilisez postgres il y a pgcrypto pour le chiffrement de niveau de base de données. (Facilite la recherche et de tri)

La meilleure idée de crypter / décrypter vos données dans la base de données même si vous avez accès au code est d'utiliser deux différentes passes un mot de passe privé (user-pass) pour chaque utilisateur et un code privé pour tous les utilisateurs (system-pass).

Scénario

  1. user-pass est stocké avec md5 dans la base de données et est utilisé pour valider chaque utilisateur pour accéder au système. Ce passe-utilisateur est différent pour chaque utilisateur.
  2. Chaque entrée d'utilisateur dans la base de données a en md5 un system-pass pour le chiffrement / déchiffrement des données. Ce système passe est même pour chaque utilisateur.
  3. Chaque fois qu'un utilisateur est retiré du système toutes les données sont cryptées sous l'ancien passe-système doivent être à nouveau crypté sous un nouveau laissez-passer du système pour éviter les problèmes de sécurité.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top