web-dev-qa-db-fra.com

Le meilleur moyen d'utiliser PHP pour chiffrer et déchiffrer les mots de passe?

Duplicate possible:
Cryptage PHP 2 voies: je dois stocker les mots de passe pouvant être récupérés

Je prévois de stocker les informations de compte étranger de mes utilisateurs sur mon site Web, à savoir nom d'utilisateur et mot de passe rapidshare, etc. .

Base64 est déchiffrable, il est donc inutile de l'utiliser simplement. Mon idée est de brouiller l'utilisateur et de le passer avant et après qu'il soit traité en base64 même après l'avoir déchiffré, vous obtenez un texte amusant si vous essayez de déchiffrer. Existe-t-il une fonction php qui accepte les valeurs qui créeront un embrouillage unique d'une chaîne et le désembrouilleront plus tard lorsque la valeur sera réintroduite?

Aucune suggestion?

214
jiexi

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

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

Pour chiffrer:

$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échiffrer:

$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 chiffre des informations, mais il n'authentifie pas le texte chiffré pour empêcher toute falsification. Vous devez ne pas compter sur un cryptage non authentifié pour la sécurité , d'autant plus que le code fourni est vulnérable aux attaques Oracle.

Voir également:

En outre, n'utilisez pas simplement un "mot de passe" pour une clé de chiffrement. Les clés de cryptage sont des chaînes aléatoires.


Démo sur 3v4l.org :

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

echo "\n";

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

Avertissement de sécurité : Cette classe n'est pas sécurisée. Il utilise Rijndael256-ECB , ce qui n’est pas sécurisé sémantiquement. Ce n'est pas parce que "ça marche" que c'est "sécurisé". En outre, il supprime les espaces de résidus par la suite en raison de la non-utilisation d'un rembourrage approprié.

Trouvé cette classe récemment, cela 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";
33
wilsonpage

Avertissement de sécurité: Ce code n'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); 
18
stasl

Une chose dont vous devez être très conscient lorsque vous utilisez le cryptage:

Essayer d'être intelligent et d'inventer vos propres affaires vous laisseront généralement avec quelque chose d'insécurisé.

Vous feriez mieux d'utiliser l'une des extensions de cryptographie fournies avec PHP.

12

Cela ne vous donnera qu'une protection marginale. Si l'attaquant peut exécuter du code arbitraire dans votre application, il peut obtenir les mots de passe de la même manière que votre application. Vous pouvez toujours vous protéger des attaques par injection SQL et des sauvegardes de bases de données égarées si vous stockez une clé secrète dans un fichier et utilisez-la pour chiffrer en allant sur la base de données et déchiffrer en sortant. Mais vous devriez utiliser bindparams pour éviter complètement le problème de l'injection SQL.

Si vous décidez de chiffrer, vous devriez utiliser une bibliothèque de chiffrement de haut niveau pour cela, sinon vous vous vous tromperez. La configuration de la clé, le remplissage des messages et les contrôles d'intégrité doivent être corrects, sinon tous vos efforts de cryptage sont peu utiles. GPGME est un bon choix pour un exemple. Mcrypt est un niveau trop bas et vous vous y tromperez probablement.

2
Ants Aasma

Avertissement: Ce code est peu sûr . En plus d'être vulnérable aux attaques par un cryptogramme choisi, sa confiance en unserialize() le rend vulnérable à PHP Object Injection.

Pour manipuler 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 flexible car vous pouvez stocker/envoyer via une URL une chaîne ou un tableau car la chaîne/le tableau est sérialisé avant le cryptage.

2
Martin

Découvrez mycrypt (): http://us.php.net/manual/en/book.mcrypt.php

Et si vous utilisez Postgres, il existe pgcrypto pour le chiffrement au niveau de la base de données. (facilite la recherche et le tri)

1
Josh Rice