Ho bisogno di crittografare alcuni dati e averli decrittografati in un secondo momento. I dati sono legati a utenti specifici. Ho raccolto due possibili soluzioni ...
1 : il primo è derivato dai documenti ufficiali (esempio # 1 @ link ):
function encrypt($toEncrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}
function decrypt($toDecrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$toDecrypt = base64_decode($toDecrypt);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($toDecrypt, $iv_size), MCRYPT_MODE_CBC, substr($toDecrypt, 0, $iv_size)));
}
La chiave viene generata una volta utilizzando:
pack('H*', bin2hex(openssl_random_pseudo_bytes(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC))));
1.1 : ho notato che il risultato cifrato termina sempre con due segni di uguale ('=='). Perché? - L'uso di bin2hex () e hex2bin () in encrypt () e decrypt () invece di base64_encode () / base64_decode () non produce questi risultati.
1.2 : L'utilizzo di bin2hex () / hex2bin () avrà conseguenze sull'esito (diverso dalla lunghezza)?
1.3 : sembra esserci qualche discussione sull'opportunità o meno di chiamare una funzione trim sul risultato di ritorno durante la decrittografia (questo vale anche per la soluzione di seguito). Perché sarebbe necessario?
2 : la seconda soluzione viene da qui, Stackoverflow ( link ):
function encrypt($key, $toEncrypt)
{
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $toEncrypt, MCRYPT_MODE_CBC, md5(md5($key))));
}
function decrypt($key, $toDecrypt)
{
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($toDecrypt), MCRYPT_MODE_CBC, md5(md5($key))), "function encrypt($toEncrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}
function decrypt($toDecrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$toDecrypt = base64_decode($toDecrypt);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($toDecrypt, $iv_size), MCRYPT_MODE_CBC, substr($toDecrypt, 0, $iv_size)));
}
");
}
Sono consapevole che entrambi gli approcci alla gestione delle chiavi sono intercambiabili, li ho volutamente resi diversi sotto questo aspetto, al fine di evidenziare le possibili soluzioni, per favore sentitevi liberi di mescolare e abbinare.
Personalmente ritengo che il primo offra una sicurezza più stretta dal momento che sia il vettore chiave che quello di inizializzazione sono correttamente randomizzati. La seconda soluzione, tuttavia, offre qualche forma di non prevedibilità poiché la chiave è unica per ogni pezzo di dati crittografati (anche se soffre della debole randomizzazione di md5 ()). Ad esempio, la chiave potrebbe essere il nome dell'utente.
3 : quindi, quale è preferibile? Sono leggermente al buio poiché la risposta StackOverflow ha ottenuto ben 105 voti. Altri pensieri, suggerimenti?
4 : domanda bonus !: Non sono incredibilmente intelligente sugli aspetti di sicurezza del server, ma ovviamente ottenere l'accesso ai file PHP potrebbe esporre la chiave, che come risultato diretto, renderebbe la crittografia inutile, presumendo che l'attaccante abbia anche accesso al DB. C'è un modo per oscurare la chiave?
Grazie per aver letto e buona giornata!