Il modo migliore per utilizzare PHP per cifrare e decifrare le password? [duplicare]
-
18-09-2019 - |
Domanda
Eventuali duplicati:
PHP crittografia a 2 vie: ho bisogno di memorizzare le password che possono essere recuperati
Ho intenzione di memorizzare le informazioni conto estero per i miei utenti sul mio sito web, alias il nome utente e la password rapidshare, ecc ... Voglio continuare a informazioni sicure, ma so che se mi hash le loro informazioni, non riesco a recuperarlo per un uso successivo.
Base64 è decifrare-in grado quindi non c'è nessun punto utilizzando tale semplicemente fuori. La mia idea è quella di rimescolare l'utente e passare prima e dopo si ottiene base64ed in questo modo anche dopo decifrare, si ottiene un testo divertente guardare se si tenta di decifrare. C'è una funzione php che accetta i valori che faranno una corsa unica di una stringa e de-scramble più tardi, quando il valore è reinputed?
Qualche suggerimento?
Soluzione
Non si dovrebbe crittografare le password, invece si dovrebbe hash utilizzando un algoritmo simile bcrypt. Questa risposta spiega come implementare correttamente la password hashing in PHP . Ancora, ecco come si potrebbe cifrare / decifrare :
$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces
per crittografare:
$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
)
);
per decifrare:
$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"
);
Attenzione : L'esempio precedente cripta le informazioni, ma non autentica il testo cifrato per evitare manomissioni. Si dovrebbe non contare su crittografia non autenticato per sicurezza , tanto più che il codice previsto è vulnerabile agli attacchi padding oracle.
Vedi anche:
- https://stackoverflow.com/a/30189841/2224584
- https://stackoverflow.com/a/30166085/2224584
- https://stackoverflow.com/a/30159120/2224584
Inoltre, non basta usare un "password" per una chiave di crittografia. Le chiavi di crittografia sono stringhe casuali.
echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="
echo "\n";
echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "
Altri suggerimenti
Avviso di protezione : questa classe non è sicuro. E 'utilizzando Rijndael256-BCE, che non è semanticamente sicuro. Proprio perché "funziona" non significa "è sicuro". Inoltre, le strisce tailing spazi in seguito a causa di non utilizzare la corretta imbottitura.
Trovato questa classe di recente, funziona come un sogno!
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);
}
}
E chiamarlo:
$str = "My secret String";
$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);
echo "$encoded<p>$decoded";
Avviso di protezione:. Questo codice non è sicura
esempio di lavoro
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);
Questo solo vi darà una protezione marginale. Se l'utente malintenzionato può eseguire codice arbitrario nell'applicazione possono ottenere presso le password esattamente nello stesso modo in cui l'applicazione può. Si potrebbe ancora ottenere una certa protezione da parte di alcuni attacchi di SQL injection e backup db fuori luogo se si memorizza una chiave segreta in un file e l'uso che per cifrare sulla strada per il db e decifrare sulla via d'uscita. Ma si dovrebbe usare bindparams evitare completamente l'emissione di SQL injection.
Se decide di cifrare, si dovrebbe usare un po 'di libreria crittografica di alto livello per questo, oppure è sbagliare. Dovrete prendere la chiave-configurazione, un messaggio di imbottitura e l'integrità dei controlli corretti, o tutti i vostri sforzi di cifratura è di scarsa utilità. GPGME è una buona scelta per un esempio. Mcrypt è troppo basso livello e probabilmente sbagliare.
Securiy Attenzione : Questo codice è insicuro . Oltre ad essere vulnerabili ad attacchi scelti-testo cifrato, la sua dipendenza da
unserialize()
lo rende vulnerabile a iniezione PHP oggetto.
Per gestire una stringa / array Uso queste due funzioni:
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;
}
È flessibile come in è possibile memorizzare / inviare tramite URL di una stringa o un array perché la stringa / array è serialzed prima della crittografia.
Scopri mycrypt (): http://us.php.net /manual/en/book.mcrypt.php
E se si sta utilizzando Postgres c'è pgcrypto per la crittografia a livello di database. (Rende più facile per cercare e ordinare)
L'idea migliore per cifrare / decifrare i dati nel database, anche se si ha accesso al codice è quello di utilizzare due diversi passaggi di una password privata (user-pass
) per ogni utente e un codice privato per tutti gli utenti (system-pass
).
Scenario
-
user-pass
viene memorizzato con md5 nel database e viene utilizzato per convalidare ogni utente di accedere al sistema. Questo passa-utente è diverso per ogni utente. - Ogni voce utente nel database ha in MD5 un
system-pass
per la crittografia / decrittografia dei dati. Questo sistema di bypass è stesso per ciascun utente. - Ogni volta che un utente viene rimosso dal sistema tutti i dati che vengono crittografati in passaggio dal sistema il vecchio devono essere cifrati di nuovo sotto un pass-nuovo sistema per evitare problemi di sicurezza.