Crittografia bidirezionale: devo archiviare le password che possono essere recuperate


174

Sto creando un'applicazione che memorizzerà le password, che l'utente può recuperare e vedere. Le password sono per un dispositivo hardware, quindi il controllo contro gli hash è fuori discussione.

Quello che devo sapere è:

  1. Come crittografare e decrittografare una password in PHP?

  2. Qual è l'algoritmo più sicuro con cui crittografare le password?

  3. Dove posso archiviare la chiave privata?

  4. Invece di archiviare la chiave privata, è una buona idea richiedere agli utenti di inserire la chiave privata ogni volta che hanno bisogno di una password decodificata? (Gli utenti di questa applicazione possono essere fidati)

  5. In che modo la password può essere rubata e decifrata? Di cosa devo essere consapevole?


1
Nota: Libsodium è ora compilato nel core PHP per> = 7.2. Questa sarebbe la soluzione "vai a" ora poiché è piena di metodi moderni a differenza di mcrypt che è considerato obsoleto ed è stato rimosso.
exhibitioner

Risposte:


212

Personalmente, userei mcryptcome gli altri pubblicati. Ma c'è molto altro da notare ...

  1. Come crittografare e decrittografare una password in PHP?

    Vedi sotto per una classe forte che si prende cura di tutto per te:

  2. Qual è l'algoritmo più sicuro con cui crittografare le password?

    più sicuro ? nessuno di loro. Il metodo più sicuro per crittografare è proteggere dalle vulnerabilità della divulgazione di informazioni (XSS, inclusione remota, ecc.). Se esce, l'attaccante può eventualmente decifrare la crittografia (nessuna crittografia non è reversibile al 100% senza la chiave - Come sottolinea @NullUserException questo non è del tutto vero. Ci sono alcuni schemi di crittografia che sono impossibili da decifrare come OneTimePad ) .

  3. Dove posso archiviare la chiave privata?

    Quello che vorrei fare è usare 3 chiavi. Uno è fornito dall'utente, uno è specifico dell'applicazione e l'altro è specifico dell'utente (come un sale). La chiave specifica dell'applicazione può essere archiviata ovunque (in un file di configurazione esterno alla radice Web, in una variabile ambientale, ecc.). Quello specifico dell'utente verrebbe archiviato in una colonna nel db accanto alla password crittografata. L'utente fornito non sarebbe stato memorizzato. Quindi, faresti qualcosa del genere:

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

    Il vantaggio è che qualsiasi 2 delle chiavi può essere compromessa senza che i dati vengano compromessi. Se c'è un attacco SQL Injection, possono ottenere $userKey, ma non l'altro 2. Se c'è un exploit del server locale, possono ottenere $userKeye $serverKey, ma non il terzo $userSuppliedKey. Se vanno a battere l'utente con una chiave inglese, possono ottenere il $userSuppliedKey, ma non l'altro 2 (ma poi di nuovo, se l'utente viene battuto con una chiave inglese, sei comunque in ritardo).

  4. Invece di archiviare la chiave privata, è una buona idea richiedere agli utenti di inserire la chiave privata ogni volta che hanno bisogno di una password decodificata? (Gli utenti di questa applicazione possono essere fidati)

    Assolutamente. In effetti, è l'unico modo in cui lo farei. Altrimenti dovresti archiviare una versione non crittografata in un formato di archiviazione durevole (memoria condivisa come APC o memcached, o in un file di sessione). Questo ti sta esponendo a ulteriori compromessi. Non archiviare mai la versione non crittografata della password in nulla tranne una variabile locale.

  5. In che modo la password può essere rubata e decifrata? Di cosa devo essere consapevole?

    Qualsiasi forma di compromesso dei sistemi consentirà loro di visualizzare i dati crittografati. Se possono iniettare codice o accedere al tuo filesystem, possono visualizzare i dati decodificati (poiché possono modificare i file che decodificano i dati). Qualsiasi forma di attacco Replay o MITM darà anche loro pieno accesso alle chiavi coinvolte. Anche annusare il traffico HTTP non elaborato fornirà loro le chiavi.

    Usa SSL per tutto il traffico. E assicurati che nulla sul server presenti alcun tipo di vulnerabilità (CSRF, XSS, SQL Injection, escalazione di privilegi, esecuzione di codice in remoto, ecc.).

Modifica: ecco un'implementazione della classe PHP di un metodo di crittografia avanzato:

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

Si noti che sto usando una funzione di aggiunto in PHP 5.6: hash_equals. Se hai un valore inferiore a 5.6, puoi utilizzare questa funzione sostitutiva che implementa una funzione di confronto sicura per i tempi usando la doppia verifica 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);
}

Uso:

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

Quindi, per decrittografare:

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

Nota che ho usato $e2la seconda volta per mostrarti che diverse istanze decodificheranno ancora correttamente i dati.

Ora, come funziona / perché usarlo su un'altra soluzione:

  1. chiavi

    • Le chiavi non vengono utilizzate direttamente. Invece, la chiave è allungata da una derivazione PBKDF2 standard.

    • La chiave utilizzata per la crittografia è unica per ogni blocco di testo crittografato. La chiave fornita diventa quindi una "chiave master". Questa classe fornisce quindi la rotazione delle chiavi per le chiavi di cifratura e autenticazione.

    • NOTA IMPORTANTE , il $roundsparametro è configurato per chiavi casuali effettive di intensità sufficiente (almeno 128 bit di Cryptographically Secure random). Se si intende utilizzare una password o una chiave non casuale (o meno casuale di 128 bit di CS casuale), è necessario aumentare questo parametro. Vorrei suggerire un minimo di 10000 per le password (più puoi permetterti, meglio, ma aggiungerà al runtime) ...

  2. Integrità dei dati

    • La versione aggiornata utilizza ENCRYPT-THEN-MAC, che è un metodo molto migliore per garantire l'autenticità dei dati crittografati.
  3. crittografia:

    • Utilizza mcrypt per eseguire effettivamente la crittografia. Suggerirei di utilizzare uno MCRYPT_BLOWFISHo dei MCRYPT_RIJNDAEL_128cypher e MCRYPT_MODE_CBCper la modalità. È abbastanza forte e ancora abbastanza veloce (un ciclo di crittografia e decrittografia richiede circa 1/2 secondo sulla mia macchina).

Ora, per quanto riguarda il punto 3 dal primo elenco, ciò che ti darebbe è una funzione come questa:

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

Potresti allungarlo nella makeKey()funzione, ma dal momento che verrà allungato in seguito, non c'è davvero un grosso punto nel farlo.

Per quanto riguarda le dimensioni di archiviazione, dipende dal testo normale. Blowfish utilizza una dimensione di blocco di 8 byte, quindi avrai:

  • 16 byte per il sale
  • 64 byte per l'hmac
  • lunghezza dei dati
  • Riempimento in modo che la lunghezza dei dati% 8 == 0

Quindi per un'origine dati a 16 caratteri, ci saranno 16 caratteri di dati da crittografare. Ciò significa che la dimensione effettiva dei dati crittografati è di 16 byte a causa del riempimento. Quindi aggiungere i 16 byte per il sale e 64 byte per l'hmac e la dimensione totale memorizzata è di 96 byte. Quindi nel migliore dei casi c'è un overhead di 80 caratteri, e nel peggiore dei casi un overhead di 87 caratteri ...

Spero che aiuti...

Nota: 12/11/12: ho appena aggiornato questa classe con un metodo di crittografia MOLTO migliore, usando chiavi derivate meglio e riparando la generazione MAC ...


3
Qualcuno non capisce cosa significhi "rompere". @IRC bel lavoro in classe, è un bel codice dannatamente bello.
jcolebrand,

1
Quanto segue restituisce false. Qualche idea sul perché? $ x = nuova crittografia (MCRYPT_BlOWFISH, MCRYPT_MODE_CBC); $ test = $ x-> encrypt ("test", "a"); echo var_dump ($ x-> decrypt ($ test, "a"));
La lunghezza d'onda del

2
Oh e ancora una volta nella funzione di decrittografia cambiando le due -64s in -128aiuto (così ottieni $enc = substr($data, 128, -128)e$mac = substr($data, -128);
cosmorogers il

4
@ircmaxell È passato un po 'di tempo dall'ultima revisione del codice, quindi mi chiedo se sia aggiornato. Devo usare qualcosa di simile per un'applicazione finanziaria e sarebbe bello se tu avessi dato un risultato
positivo

2
Avvertimento! L'estensione mcrypt è stata abbandonata da quasi un decennio ormai, ed era anche abbastanza complessa da usare. È stato quindi deprecato a favore di OpenSSL, dove verrà rimosso dal core e in PECL in PHP 7.2. th1.php.net/manual/en/migration71.deprecated.php
vee

15

Come crittografare e decrittografare una password in PHP? Implementando uno dei tanti algoritmi di crittografia. (o usando una delle tante librerie)

Qual è l'algoritmo più sicuro con cui crittografare le password? Esistono tonnellate di algoritmi diversi, nessuno dei quali è sicuro al 100%. Ma molti di loro sono abbastanza sicuri per il commercio e persino per scopi militari

Dove posso archiviare la chiave privata? Se hai deciso di implementare la chiave pubblica - algoritmo di crittografia (ad esempio RSA), non memorizzi la chiave privata. l'utente ha una chiave privata. il tuo sistema ha una chiave pubblica che può essere archiviata ovunque tu voglia.

Invece di archiviare la chiave privata, è una buona idea richiedere agli utenti di inserire la chiave privata ogni volta che hanno bisogno di una password decodificata? (Gli utenti di questa applicazione possono essere fidati) Beh, se il tuo utente può ricordare numeri primi ridicolmente lunghi allora - sì, perché no. Ma in genere è necessario elaborare il sistema che consentirà all'utente di memorizzare la propria chiave da qualche parte.

In che modo la password può essere rubata e decifrata? Di cosa devo essere consapevole? Questo dipende dall'algoritmo utilizzato. Tuttavia, assicurarsi sempre di non inviare la password non crittografata da o verso l'utente. O crittografarlo / decrittografarlo sul lato client o utilizzare https (o altri mezzi crittografici dell'utente per proteggere la connessione tra server e client).

Tuttavia, se tutto ciò che serve è archiviare le password in modo crittografato, ti suggerirei di utilizzare un semplice XOR Cipher. Il problema principale con questo algoritmo è che potrebbe essere facilmente risolto dall'analisi della frequenza. Tuttavia, poiché in genere le password non sono composte da lunghi paragrafi di testo inglese, non credo che dovresti preoccupartene. Il secondo problema con XOR Cipher è che se si dispone di un messaggio sia in forma crittografata che decifrata, è possibile trovare facilmente la password con cui è stata crittografata. Ancora una volta, non è un grosso problema nel tuo caso in quanto riguarda solo l'utente che è già stato compromesso con altri mezzi.


Alla risposta 3, quando dici che gli utenti hanno una chiave privata, non capisco cosa significhi. Non è consigliabile passare manualmente le chiavi private nell'applicazione, quindi in quale altro modo le chiavi private vengono passate all'applicazione?
HyderA

Bene, questo è un po 'un problema. La chiave privata può essere memorizzata nel file di testo e quindi copiata incollata nell'app. La chiave potrebbe anche essere memorizzata sul server, ma in questo caso dovrebbe comunque essere crittografata con alcuni altri algoritmi di crittografia come XOR. L'uso di XOR qui in questo caso è abbastanza sicuro in quanto esiste solo una coppia password-messaggio e il messaggio è abbastanza casuale, quindi l'analisi a frequenza fredda non può essere utilizzata.
Ivan

4
Certamente non consiglierei di implementare un algoritmo di crittografia, ci sono troppe insidie ​​e le librerie esistenti sono state testate e analizzate da molte persone.
Orecchie lunghe

Il problema principale con XOR è che se qualcuno ruba i dati dell'applicazione e conosce solo una delle password di un utente, può decrittografare tutte le altre password per quell'utente.
Orecchie lunghe

1
@Ivan: sì, ma questo è uno dei casi in cui penso che il fai-da-te sia davvero brutto a meno che tu non capisca VERAMENTE la crittografia. Esistono cifre forti, perché non usarle?
Ircmaxell,

13
  1. La funzione PHP che stai cercando è Mcrypt ( http://www.php.net/manual/en/intro.mcrypt.php ).

L'esempio del manuale è leggermente modificato per questo esempio):

<?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";
?>

Dovresti usare mcrypt_decrypt per decrittografare la tua password.

  1. L' algoritmo migliore è piuttosto soggettivo: chiedi a 5 persone, ottieni 5 risposte. Personalmente se il valore predefinito (Blowfish) non è abbastanza buono per te, probabilmente hai problemi più grandi!

  2. Dato che PHP è necessario per crittografare - non sono sicuro di poterlo nascondere ovunque - graditi commenti su questo. Ovviamente si applicano le migliori pratiche di codifica PHP standard!

  3. Dato che la chiave di crittografia sarà comunque nel tuo codice, non sei sicuro di ciò che otterrai, a condizione che il resto dell'applicazione sia sicuro.

  4. Ovviamente, se la password crittografata e la chiave di crittografia vengono rubate, il gioco finisce.

Metterei un pilota sulla mia risposta - non sono un esperto di crittografia PHP, ma, penso che ciò a cui ho risposto sia una pratica standard - accolgo con favore commenti che altri potrebbero avere.


$pass = $text. Penso che l'abbia cambiato per soddisfare la domanda e non si è accorto della seconda occorrenza.
HyderA

3
Due cose da notare. Innanzitutto, MCRYPT_MODE_ECBnon usa un IV. In secondo luogo, se lo facesse, dovresti archiviare il IV in quanto non puoi decrittografare i dati senza di esso ...
Ircmaxell,

"L'algoritmo migliore è piuttosto soggettivo: chiedi a 5 persone, ottieni 5 risposte. Personalmente se il valore predefinito (Blowfish) non è abbastanza buono per te, probabilmente hai problemi più grandi!" Questo è totalmente sbagliato. Qualsiasi esperto di crittografia sarà più o meno d'accordo con gist.github.com/tqbf/be58d2d39690c3b366ad che esclude specificamente il pesce palla
Scott Arciszewski,

6

Molti utenti hanno suggerito di utilizzare mcrypt ... il che è corretto, ma mi piace fare un passo avanti per renderlo facilmente memorizzato e trasferibile (poiché a volte i valori crittografati possono renderli difficili da inviare utilizzando altre tecnologie come curl o json) .

Dopo aver crittografato correttamente utilizzando mcrypt, eseguirlo tramite base64_encode e quindi convertirlo in codice esadecimale. Una volta in codice esadecimale è facile da trasferire in vari modi.

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

E dall'altra parte:

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


2
Beh, era nel 2011: P
Bradley,

5

Suggerirei la crittografia della chiave pubblica solo se desideri la possibilità di impostare la password di un utente senza la sua interazione (questo può essere utile per reimpostare e password condivise).

Chiave pubblica

  1. L' estensione OpenSSL , in particolare openssl_public_encrypteopenssl_private_decrypt
  2. Questo sarebbe RSA semplice supponendo che le tue password si adattino alla dimensione della chiave - riempimento, altrimenti hai bisogno di un livello simmetrico
  3. Archivia entrambe le chiavi per ciascun utente, la passphrase della chiave privata è la password dell'applicazione

simmetrico

  1. L' estensione Mcrypt
  2. AES-256 è probabilmente una scommessa sicura, ma questa potrebbe essere una domanda SO in sé
  3. No, questa sarebbe la password della loro applicazione

Tutti e due

4. Sì, gli utenti dovrebbero inserire la password dell'applicazione ogni volta, ma memorizzarla nella sessione solleverebbe altri problemi

5.

  • Se qualcuno ruba i dati dell'applicazione, è sicuro quanto la cifra simmetrica (per lo schema di chiave pubblica, viene utilizzata per proteggere la chiave privata con la passphrase).
  • La tua applicazione dovrebbe essere sicuramente accessibile solo su SSL, preferibilmente utilizzando i certificati client.
  • Prendi in considerazione l'aggiunta di un secondo fattore per l'autenticazione che verrebbe utilizzato solo una volta per sessione, come un token inviato tramite SMS.

Evita mcrypt, stai attento openssl_private_decrypt().
Scott Arciszewski,

2

Ho provato qualcosa del genere, ma tieni presente che non sono crittografo né in possesso di conoscenze approfondite phpo di alcun linguaggio di programmazione. È solo un'idea. La mia idea è quella di archiviare keyin qualche file o database(o inserire manualmente) quale (posizione) non può essere facilmente previsto (E ovviamente un giorno qualsiasi cosa verrà decifrata, il concetto è quello di allungare il tempo di decodifica) e crittografare le informazioni sensibili.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "myemail@domain.com";
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.

Si prega di notare che è solo un concetto. Qualsiasi miglioramento su questo codice sarebbe molto apprezzabile.


2

Le password sono per un dispositivo hardware, quindi il controllo contro gli hash è fuori discussione

Eh? Non capisco. Vuoi dire che la password deve essere recuperabile?

Come altri hanno già detto, l'estensione mcrypt fornisce l'accesso a molte funzioni crittografiche - tuttavia stai invitando i tuoi utenti a mettere tutte le loro uova in un paniere - uno che sarà potenzialmente un bersaglio per gli aggressori - e se non lo sai nemmeno come iniziare a risolvere il problema, quindi stai facendo un disservizio ai tuoi utenti. Non sei in grado di capire come proteggere i dati.

La maggior parte delle vulnerabilità di sicurezza non deriva dal fatto che l'algoritmo sottostante è difettoso o insicuro, ma a causa di problemi con il modo in cui l'algoritmo viene utilizzato nel codice dell'applicazione.

Detto questo, è possibile costruire un sistema ragionevolmente sicuro.

Dovresti considerare la crittografia asimmetrica solo se hai l'obbligo per un utente di creare un messaggio sicuro che è leggibile da un altro utente (specifico). Il motivo è che è computazionalmente costoso. Se si desidera semplicemente fornire un repository per consentire agli utenti di immettere e recuperare i propri dati, la crittografia simmetrica è adeguata.

Se, tuttavia, si memorizza la chiave per decrittografare il messaggio nello stesso posto del messaggio crittografato (o in cui è archiviato il messaggio crittografato), il sistema non è sicuro. Utilizzare lo stesso token per l'autenticazione dell'utente come per la chiave di decrittografia (o, nel caso della crittografia assimetrica, utilizzare il token come passphrase della chiave privata). Poiché sarà necessario archiviare il token sul server in cui la decrittografia viene eseguita almeno temporaneamente, è possibile prendere in considerazione l'utilizzo di un substrato di archiviazione della sessione non ricercabile o il passaggio del token direttamente a un demone associato alla sessione che memorizzerà il token in memoria ed eseguire la decrittazione dei messaggi su richiesta.


1

Usa password_hash e 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";
?>

E per decifrare:

<?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.';
}
?>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.