Najlepszy sposób użycia PHP do szyfrowania i deszyfrowania haseł? [duplikat]

Możliwy duplikat:
PHP 2-way encryption: muszę przechowywać hasła, które można pobrać

Planuję przechowywać informacje o kontach zagranicznych dla moich użytkowników na mojej stronie, czyli nazwy użytkownika i hasła rapidshare itp... Chcę, aby informacje były bezpieczne, ale wiem, że jeśli zaszyfruję ich informacje, nie mogę ich odzyskać do późniejszego wykorzystania.

Base64 jest w stanie odszyfrować, więc nie ma sensu używać tego po prostu off. Mój pomysł polega na tym, aby scramble użytkownika i podaj przed i po tym, jak dostanie się base64ed w ten sposób, nawet po odszyfrowaniu go, dostaniesz jakiś śmieszny tekst, jeśli spróbujesz odszyfrować. Czy istnieje funkcja php, która akceptuje wartości, które sprawią, że unikalny scramble łańcucha i de-scramble go później, gdy wartość jest reinputed?

Jakieś sugestie?
Author: Community, 2009-08-17

8 answers

Nie powinieneś szyfrować haseł, zamiast tego powinieneś je zaszyfrować za pomocą algorytmu takiego jak bcrypt. Ta odpowiedź wyjaśnia jak poprawnie zaimplementować hashowanie haseł w PHP . nadal, oto jak można zaszyfrować/odszyfrować:

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

Aby Zaszyfrować:

$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
    )
);

Aby Odszyfrować:

$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"
);

Ostrzeżenie : powyższy przykład szyfruje informacje, ale nie uwierzytelnia zaszyfrowanego tekstu, aby zapobiec manipulacji. powinieneś Nie polegaj na nieautoryzowanym szyfrowaniu dla bezpieczeństwa , zwłaszcza że podany kod jest podatny na ataki padding Oracle.

Zobacz też:

Ponadto nie używaj tylko "hasła" do klucza szyfrowania. klucze szyfrowania są losowe struny.


Demo na 3v4l.org :

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

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "
 292
Author: Alix Axel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:59

Ostrzeżenie Bezpieczeństwa : ta klasa nie jest Bezpieczna. Używa Rijndael256-EBC , co nie jest semantycznie bezpieczne. To, że " to działa "nie znaczy, że jest bezpieczne. Ponadto usuwa przestrzenie ogonowe z powodu braku odpowiedniej wyściółki.

Znalazłem tę klasę niedawno, to działa jak marzenie!

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);
    }
}

I nazwać go:

$str = "My secret String";

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

echo "$encoded<p>$decoded";
 34
Author: wilsonpage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 08:21:15

Ostrzeżenie Bezpieczeństwa: Ten kod nie jest bezpieczny.

Przykład roboczy

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
Author: stasl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 08:15:43

Jedna rzecz, o której powinieneś być bardzo świadomy, mając do czynienia z szyfrowaniem:

Próba bycia mądrym i wymyślania własnych rzeczy zwykle pozostawi cię z czymś niepewnym.

Prawdopodobnie najlepiej byłoby użyć jednego z rozszerzeń kryptograficznych , które są dostarczane z PHP.

 12
Author: Sebastian Paaske Tørholm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-17 16:50:07

Securiy Warning : Ten kod jest niepewny . Oprócz tego, że jest podatny na ataki za pomocą wybranego szyfru, jego zależność od unserialize() sprawia, że jest podatny na iniekcję obiektów PHP.

Do obsługi łańcucha / tablicy używam tych dwóch funkcji:

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;
}

Jest elastyczny, ponieważ możesz przechowywać/wysyłać przez URL ciąg znaków lub tablicę, ponieważ ciąg / tablica jest serializowana przed szyfrowaniem.

 3
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 08:16:56

To daje tylko marginalną ochronę. Jeśli atakujący może uruchomić dowolny kod w Twojej aplikacji, może uzyskać hasła w dokładnie taki sam sposób, jak Twoja aplikacja. Nadal możesz uzyskać ochronę przed atakami SQL injection i błędnymi kopiami zapasowymi db, jeśli przechowasz tajny klucz w pliku i użyjesz go do szyfrowania w drodze do bazy danych i odszyfrowania w drodze wyjścia. Ale powinieneś użyć bindparams, aby całkowicie uniknąć problemu SQL injection.

Jeśli zdecydujesz się na Szyfruj, powinieneś użyć do tego jakiejś biblioteki kryptograficznej wysokiego poziomu, albo się pomylisz. Musisz poprawnie skonfigurować klucz, wypełnianie wiadomości i sprawdzanie integralności, w przeciwnym razie cały wysiłek szyfrowania będzie mało przydatny. GPGME jest dobrym wyborem na jeden przykład. Mcrypt jest zbyt niski poziom i prawdopodobnie się pomylisz.

 2
Author: Ants Aasma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-17 16:53:45

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

A jeśli używasz postgres jest pgcrypto do szyfrowania poziomu bazy danych. (ułatwia wyszukiwanie i sortowanie)

 1
Author: Josh Rice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-17 16:50:59

Najlepszym pomysłem, aby zaszyfrować/odszyfrować dane w bazie danych, nawet jeśli masz dostęp do kodu, jest użycie 2 różnych przejść prywatne hasło (user-pass) dla każdego użytkownika i prywatny kod dla wszystkich użytkowników (system-pass).

Scenariusz

  1. user-pass jest przechowywany z md5 w bazie danych i jest używany do weryfikacji każdego użytkownika, aby zalogować się do systemu. Ten user-pass jest inny dla każdego użytkownika.
  2. każdy wpis użytkownika w bazie ma w md5 a system-pass dla szyfrowanie / deszyfrowanie danych. Ten system-pass jest tym samym dla każdego użytkownika.
  3. za każdym razem, gdy użytkownik jest usuwany z systemu, wszystkie dane, które są zaszyfrowane w starym systemie, muszą być ponownie zaszyfrowane w Nowym Systemie, aby uniknąć problemów z bezpieczeństwem.
 0
Author: Nikos Tsirakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-18 15:19:24