Szyfrowanie dwukierunkowe: muszę przechowywać hasła, które można odzyskać

Tworzę aplikację, która będzie przechowywać hasła, które użytkownik może pobrać i zobaczyć. Hasła są dla urządzenia sprzętowego, więc sprawdzanie hashów nie wchodzi w grę.

To co muszę wiedzieć to:

  1. Jak zaszyfrować i odszyfrować hasło w PHP?

  2. Jaki jest najbezpieczniejszy algorytm szyfrowania haseł?

  3. Gdzie mogę przechowywać klucz prywatny?

  4. Zamiast przechowywać klucz prywatny, jest to dobry pomysł, aby wymagać od użytkowników wprowadzenia klucza prywatnego za każdym razem, gdy potrzebują odszyfrowanego hasła? (Użytkownicy tej aplikacji mogą być zaufani)

  5. W Jaki Sposób można ukraść i odszyfrować hasło? O czym muszę wiedzieć?

Author: jww, 2011-02-23

8 answers

Osobiście użyłbym mcrypt tak jak inni zamieszczeni. Ale jest o wiele więcej do odnotowania...

  1. Jak zaszyfrować i odszyfrować hasło w PHP?

    Zobacz poniżej silną klasę, która dba o wszystko za Ciebie:

  2. Jaki jest najbezpieczniejszy algorytm szyfrowania haseł?

    najbezpieczniejszy ? żadnego z nich. Najbezpieczniejszą metodą szyfrowania jest ochrona przed lukami w zabezpieczeniach (XSS, zdalne włączenie, itp.). Jeśli się wydostanie, atakujący może w końcu złamać szyfrowanie (żadne szyfrowanie nie jest w 100% nieodwracalne bez klucza - jak wskazuje @NullUserException, nie jest to do końca prawdą. Istnieją pewne schematy szyfrowania, które są niemożliwe do złamania, takie jak OneTimePad ).

  3. Gdzie przechowywać klucz prywatny?

    To, co bym zrobił, to użyć 3 klawiszy. Jeden jest dostarczany przez użytkownika, jeden jest specyficzny dla aplikacji, a drugi jest specyficzny dla użytkownika (jak sól). Klucz specyficzny dla aplikacji może być przechowywany w dowolnym miejscu (w pliku konfiguracyjnym poza web-rootem, w zmiennej środowiskowej, itd.). Konkretny użytkownik będzie przechowywany w kolumnie w db obok zaszyfrowanego hasła. Dostarczony przez użytkownika nie będzie przechowywany. Wtedy zrobiłbyś coś takiego:

    $key = $userKey . $serverKey . $userSuppliedKey;
    

    Korzyść polega na tym, że dowolne dwa klucze mogą zostać naruszone bez naruszania danych. Jeśli jest atak SQL Injection, mogą uzyskać $userKey, ale nie pozostałe 2. Jeśli istnieje lokalny exploit serwera, mogą uzyskać $userKey i $serverKey, ale nie trzeci $userSuppliedKey. Jeśli pobić użytkownika kluczem, może dostać $userSuppliedKey, ale nie pozostałe 2 (ale z drugiej strony, jeśli użytkownik zostanie pobity kluczem, i tak jest za późno).

  4. Zamiast przechowywać klucz prywatny, czy dobrym pomysłem jest wymaganie od użytkowników wprowadzenia klucza prywatnego w każdej chwili, gdy potrzebują odszyfrowanego hasła? (Użytkownicy tej aplikacji mogą być zaufany)

    Absolutnie. Właściwie, to jedyny sposób, w jaki bym to zrobił. W przeciwnym razie konieczne byłoby przechowywanie niezaszyfrowanej wersji w trwałym formacie pamięci masowej (pamięć współdzielona, taka jak APC lub memcached, lub w pliku sesji). To narażanie się na dodatkowe kompromisy. Nigdy nie przechowuj niezaszyfrowanej wersji hasła w niczym innym niż w zmiennej lokalnej.
  5. W jaki sposób można ukraść i odszyfrować hasło? O czym muszę wiedzieć?

    Any forma kompromisu Twoich systemów pozwoli im przeglądać zaszyfrowane dane. Jeśli mogą wprowadzić kod lub dostać się do systemu plików, mogą przeglądać odszyfrowane dane (ponieważ mogą edytować pliki, które odszyfrowują dane). Każda forma powtórki lub ataku MITM daje im również pełny dostęp do zaangażowanych kluczy. Wąchanie surowego ruchu HTTP również da im klucze.

    Użyj SSL dla całego ruchu. I upewnij się, że nic na serwerze nie ma żadnych luk (CSRF, XSS, SQL Injection, Eskalacja uprawnień, zdalne wykonywanie kodu, itp.).

Edit: oto Implementacja klasy PHP silnej metody szyfrowania:

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

Zauważ, że używam funkcji dodanej w PHP 5.6: hash_equals. Jeśli jesteś na niższym niż 5.6, możesz użyć tej funkcji zastępczej, która implementuje funkcję bezpieczne porównanie za pomocą podwójnej weryfikacji HMAC :

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

Użycie:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

Następnie, aby odszyfrowanie:

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

Zauważ, że użyłem $e2 po raz drugi, aby pokazać, że różne instancje nadal poprawnie odszyfrowują dane.

Teraz, Jak to działa/po co używać go nad innym rozwiązaniem:

  1. Klucze

    • Klucze nie są używane bezpośrednio. Zamiast tego klucz jest rozciągany przez standardową wyprowadzenie PBKDF2.

    • Klucz używany do szyfrowania jest unikalny dla każdego zaszyfrowanego bloku tekstu. Dostarczony klucz staje się zatem "master key". Klasa ta zapewnia zatem obrót klucza dla kluczy szyfrowych i auth.

    • WAŻNA UWAGA , parametr $rounds jest skonfigurowany dla prawdziwych kluczy losowych o wystarczającej sile (co najmniej 128 bitów Kryptograficznie zabezpieczonego losowego). Jeśli chcesz użyć hasła lub klucza nie-losowego (lub mniej losowego niż 128 bitów CS random), musisz zwiększyć ten parametr. Proponuję minimum 10000 za hasła (im więcej Cię stać, tym lepiej, ale doda do runtime)...

  2. Integralność Danych

    • zaktualizowana wersja używa ENCRYPT-THEN-MAC, co jest znacznie lepszą metodą zapewnienia autentyczności zaszyfrowanych danych.
  3. Szyfrowanie:

    • używa mcrypt, aby faktycznie wykonać szyfrowanie. Sugerowałbym użycie MCRYPT_BLOWFISH lub MCRYPT_RIJNDAEL_128 cypherów i MCRYPT_MODE_CBC dla trybu. Jest wystarczająco mocny, a mimo to dość szybki (szyfrowanie i cykl deszyfrowania trwa około 1/2 sekundy na mojej maszynie).

Teraz, co do punktu 3 z pierwszej listy, to co dałoby ci funkcję taką jak ta:

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

Możesz go rozciągnąć w funkcji makeKey(), ale ponieważ będzie on rozciągany później, nie ma w tym wielkiego sensu.

Jeśli chodzi o rozmiar pamięci, zależy to od zwykłego tekstu. Blowfish używa bloku o rozmiarze 8 bajtów, więc będziesz miał:

  • 16 bajtów dla sól
  • 64 bajty dla hmac
  • Długość danych
  • Padding tak, aby długość danych % 8 = = 0

Więc dla 16-znakowego źródła danych, będzie 16 znaków danych do zaszyfrowania. Oznacza to, że rzeczywisty rozmiar zaszyfrowanych danych wynosi 16 bajtów z powodu wypełnienia. Następnie dodaj 16 bajtów dla salt i 64 bajtów dla hmac, a całkowity przechowywany rozmiar wynosi 96 bajtów. Więc w najlepszym wypadku jest 80 znaków nad głową, a w najgorszym 87 znaków nad głową...

I mam nadzieję, że to pomoże...

Uwaga: 12/11/12: właśnie zaktualizowałem tę klasę o znacznie lepszą metodę szyfrowania, używając lepiej pochodnych kluczy i naprawiając generację komputerów MAC...

 203
Author: ircmaxell,
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
2015-05-27 13:18:25

Jak zaszyfrować i odszyfrować hasło w PHP? Implementując jeden z wielu algorytmów szyfrowania. (lub używając jednej z wielu bibliotek)

Jaki jest najbezpieczniejszy algorytm szyfrowania haseł? Istnieje mnóstwo różnych algorytmów, z których żaden nie jest w 100% bezpieczny. Ale wiele z nich jest wystarczająco bezpiecznych dla handlu, a nawet celów wojskowych

Gdzie mogę przechowywać klucz prywatny? Jeśli zdecydowałeś się wdrożyć klucz publiczny-algorytm kryptograficzny (np. RSA), nie przechowuje się klucza prywatnego. użytkownik posiada klucz prywatny. Twój system ma klucz publiczny, który może być przechowywany w dowolnym miejscu.

czy zamiast przechowywać klucz prywatny, dobrym pomysłem jest wymaganie od użytkowników wprowadzenia klucza prywatnego za każdym razem, gdy potrzebują odszyfrowanego hasła? (Użytkownicy tej aplikacji mogą być zaufani) Cóż, jeśli twój użytkownik może zapamiętać absurdalnie długie liczby pierwsze , to-tak, dlaczego nie. Ale ogólnie trzeba by przyjść się z systemem, który pozwoli użytkownikowi przechowywać swój klucz gdzieś.

w jaki sposób można ukraść i odszyfrować hasło? O czym muszę wiedzieć? Zależy to od zastosowanego algorytmu. Jednak zawsze upewnij się, że nie wysyłasz niezaszyfrowanego hasła do lub od użytkownika. Szyfruj / odszyfruj po stronie klienta lub użyj https (lub innych kryptograficznych środków użytkownika w celu zabezpieczenia połączenia między serwerem a klientem).

Jednak jeśli wszystko czego potrzebujesz to przechowuj hasła w zaszyfrowany sposób, sugerowałbym użycie prostego szyfru XOR. Głównym problemem tego algorytmu jest to, że można go łatwo złamać przez analizę częstotliwości. Jednak jako, że ogólnie hasła nie są tworzone z długich akapitów tekstu angielskiego, nie sądzę, że powinieneś się tym martwić. Drugi problem z szyfrem XOR polega na tym, że jeśli masz wiadomość zarówno w formie zaszyfrowanej, jak i odszyfrowanej, możesz łatwo znaleźć hasło, za pomocą którego została zaszyfrowana. Ponownie, nie jest to duży problem w Twoim przypadek, ponieważ dotyczy tylko użytkownika, który został już skompromitowany innymi środkami.

 14
Author: Ivan,
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
2011-02-23 11:49:22
  1. funkcja PHP, której szukasz to Mcrypt ( http://www.php.net/manual/en/intro.mcrypt.php).

Przykład z podręcznika jest lekko edytowany dla tego przykładu):

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

Użyłbyś mcrypt_decrypt Aby odszyfrować hasło.

  1. Najlepszy algorytm jest raczej subiektywny-zapytaj 5 osób, Uzyskaj 5 odpowiedzi. Osobiście, jeśli domyślne (Blowfish) nie jest wystarczająco dobry dla Ciebie, prawdopodobnie masz większe problemy!

  2. Biorąc pod uwagę, że jest on potrzebny przez PHP do szyfrowania - Nie wiem, czy można go ukryć gdziekolwiek - mile widziane komentarze na ten temat. Standard PHP stosuje się oczywiście najlepsze praktyki kodowania!

  3. Biorąc pod uwagę, że klucz szyfrowania i tak będzie w kodzie, Nie wiem, co zyskasz, pod warunkiem, że reszta aplikacji jest Bezpieczna.

  4. Oczywiście, jeśli zaszyfrowane hasło i klucz szyfrowania zostaną skradzione, gra skończona.

I ' d put a rider on my answer - Nie jestem ekspertem od krypto PHP, ale myślę, że to, na co odpowiedziałem, jest standardową praktyką - mile widziane są komentarze, które mogą mieć inni.

 12
Author: Jon Rhoades,
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
2013-12-22 04:44:05

Wielu użytkowników zasugerowało użycie mcrypt... co jest poprawne, ale lubię iść o krok dalej, aby łatwo go przechowywać i przesyłać (ponieważ czasami zaszyfrowane wartości mogą sprawić, że będą trudne do wysłania za pomocą innych technologii, takich jak curl lub json).

Po pomyślnym zaszyfrowaniu za pomocą mcrypt, uruchom go przez base64_encode, a następnie przekonwertuj go na kod szesnastkowy. Raz w kodzie szesnastkowym można go łatwo przenieść na wiele sposobów.

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $unencrypted);
$encrypted = $ua."||||".$iv;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$encrypted = base64_encode($encrypted);
$encrypted = array_shift(unpack('H*', $encrypted));

I po drugiej stronie:

$encrypted = pack('H*', $encrypted);
$encrypted = base64_decode($encrypted);
list($encrypted,$iv) = explode("||||",$encrypted,2);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$unencrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
 6
Author: Bradley,
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
2011-02-25 23:20:21

Sugerowałbym tylko szyfrowanie klucza publicznego, jeśli chcesz mieć możliwość ustawienia hasła użytkownika bez ich interakcji (może to być przydatne w przypadku resetów i współdzielonych haseł).

Klucz publiczny

  1. rozszerzenie OpenSSL, w szczególności openssl_public_encrypt i openssl_private_decrypt
  2. byłoby to proste RSA zakładając, że Twoje hasła będą pasowały do wypełnienia rozmiaru klucza, w przeciwnym razie potrzebujesz warstwy symetrycznej
  3. przechowywać oba klucze dla każdego użytkownika, hasło klucza prywatnego jest ich hasło aplikacji

Symetryczne

  1. TheMcrypt extension
  2. AES-256 jest prawdopodobnie bezpiecznym zakładem, ale może to być pytanie samo w sobie.]}
  3. nie wiesz - to byłoby hasło ich aplikacji

Oba

4. Tak-użytkownicy musieliby za każdym razem wprowadzać hasło do aplikacji, ale przechowywanie go w sesji rodziłoby inne problemy

5.

  • Jeśli ktoś kradnie dane aplikacji, to jako zabezpieczony jako szyfr symetryczny (w schemacie klucza publicznego służy do ochrony klucza prywatnego za pomocą hasła.)
  • Twoja aplikacja powinna być dostępna tylko przez SSL, najlepiej przy użyciu certyfikatów klienta.
  • rozważ dodanie drugiego czynnika uwierzytelniania, który byłby używany tylko raz na sesję, np. token wysyłany SMS-em.
 5
Author: Long Ears,
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
2011-02-23 11:57:33

Próbowałem czegoś takiego, ale proszę zauważyć, że nie jestem kryptografem ani nie posiadam dogłębnej wiedzy o php lub jakimkolwiek języku programowania. To tylko pomysł. Moim pomysłem jest, aby przechowywać key w jakimś pliku lub database (lub wprowadzić ręcznie), którego(lokalizacja) nie można łatwo przewidzieć (i oczywiście wszystko zostanie kiedyś odszyfrowane, koncepcja polega na wydłużeniu czasu deszyfrowania) i szyfrować poufne informacje.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "[email protected]";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

Proszę zauważyć, że to tylko koncepcja. Wszelkie ulepszenia w tym kodzie byłoby to bardzo cenne.

 2
Author: Santosh Linkha,
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
2011-03-01 04:29:28

Hasła są dla urządzenia sprzętowego, więc sprawdzanie hashów nie wchodzi w grę

Eh? Nie rozumiem. Czy chodzi Ci tylko o to, że hasło musi być odzyskiwalne?

Jak już powiedzieli inni, rozszerzenie mcrypt zapewnia dostęp do wielu funkcji kryptograficznych - jednak zachęcasz użytkowników do umieszczania wszystkich jajek w jednym koszyku - takim, który potencjalnie będzie celem dla atakujących - a jeśli nawet nie wiesz, jak zacząć rozwiązywać problem wtedy robisz swoim użytkownikom krzywdę. Nie jesteś w stanie zrozumieć, jak chronić dane.

Większość luk w zabezpieczeniach pojawia się nie dlatego, że algorytm bazowy jest wadliwy lub niepewny - ale z powodu problemów ze sposobem, w jaki algorytm jest używany w kodzie aplikacji.

Powiedziawszy to, jest możliwe zbudować w miarę bezpieczny system.

Powinieneś rozważyć szyfrowanie asymetryczne tylko, jeśli masz wymagania dotyczące użytkownika aby utworzyć bezpieczną wiadomość, która jest czytelna dla innego (konkretnego) użytkownika. Powodem jest to, że jego koszt obliczeniowy. Jeśli chcesz po prostu udostępnić repozytorium, w którym użytkownicy mogą wprowadzać i pobierać własne dane, odpowiednie jest szyfrowanie symetryczne.

Jeśli jednak przechowujesz klucz do odszyfrowania wiadomości w tym samym miejscu co zaszyfrowana wiadomość (lub gdzie przechowywana jest zaszyfrowana wiadomość), system nie jest bezpieczny. Użyj tego samego tokena do uwierzytelniania użytkownika, co dla klucz deszyfrujący (lub w przypadku szyfrowania asymetrycznego użyj tokenu jako frazy klucza prywatnego). Ponieważ token będzie musiał być przechowywany przynajmniej tymczasowo na serwerze, na którym odbywa się odszyfrowanie, warto rozważyć użycie substratu do przechowywania sesji, którego nie można przeszukiwać, lub przekazanie tokenu bezpośrednio do demona powiązanego z sesją, który przechowywałby token w pamięci i wykonywałby deszyfrowanie wiadomości na żądanie.

 2
Author: symcbean,
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
2011-03-01 10:33:05

Użyj password_hash i password_verify

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

I odszyfrować:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>
 1
Author: jvitoroc,
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-09-24 22:51:26