2014-07-22 15 views
6

Dato che Laravel's Crypt aggiunge sempre sale, quindi non esistono due istanze della stessa crittografia uguali.Cripta di Laravel - Confronto dei valori

Normalmente, questo va bene perché posso confrontare la versione decifrata dei due. Tuttavia, cosa succede se voglio cercare un valore che è criptato nel database?

Dire che ho un tavolo users e vorrei criptare l'indirizzo email. Ora voglio trovare qualcuno tramite l'e-mail [email protected].

Come faccio a scrivere la query per questo? Non riesco solo a Crypt::encrypt($email) e ricerca poiché questa iterazione di encrypt sarà diversa da quella nel DB.

Modifica

Attualmente, l'unica cosa che posso pensare è quello di ottenere tutti, e filtrare attraverso di loro:

$match = User::all()->filter(function($record) use($email) { 
      $field = $record->email['email']; 

      if(Crypt::decrypt($field) == $email) return $record; 
     }); 

ma questo è terribile. Non voglio cercare in tutto.

+3

Credo che l'unico modo per aggirare questo sarebbe per crittografare i dati utilizzando un 'key' fisso e' iv'. Non sarebbe difficile estendere la classe Crypt per farlo. – Jeemusu

+0

Si potrebbe prendere in considerazione l'aggiunta di un'altra colonna con un hash della posta elettronica che è possibile confrontare. –

risposta

2

Come descritto, non è possibile. La risposta che hai dato è il modo in cui lo realizzerai se non hai bisogno di ottimizzarlo.

Se si ha bisogno di ottimizzarlo senza completamente compromettere il valore criptato, e si è profilata per trovare la quantità di dati restituiti ed elaborati dal vostro filtro è una delle principali cause di ritardo, è possibile effettuare le seguenti operazioni.

Aggiungi un nuovo campo alla tabella che memorizzerà un sottoinsieme di un hash. A seconda del numero di indirizzi e-mail univoci, è possibile ottimizzare l'ampiezza di questo sottoinsieme. Nota: minore è il migliore, poiché si stanno perdendo alcune informazioni sul valore crittografato utilizzando questo approccio. Ad esempio, se si memorizza un hash da 1 byte dell'indirizzo e-mail, si riduce l'entropia della crittografia di ~ 8 bit.

Quando si interroga, creare prima il sottoinsieme di hash dell'email e inserire una clausola where per restituire solo tali righe.

Tutto ciò presuppone che la funzione di hash sia più economica della fase di decrittografia. Questo approccio richiede di ricalcolare tutti i sottoinsiemi di hash se si desidera aumentarne le dimensioni, quindi scegliere una dimensione che aumenti significativamente le prestazioni, non comprometta indebitamente la crittografia e molto probabilmente non avrà bisogno di cambiare man mano che si cresce è importante .

Nota: non utilizzare un hash lineare come MD5 in questa situazione. Non a causa della sua suscettibilità alle collisioni, ma perché lo spazio chiave sarà così piccolo. Se le prestazioni sono importanti e si memorizzano grandi quantità di dati, si aprono attacchi DOS in cui l'utente malintenzionato crea grandi quantità di indirizzi e-mail che eseguono tutti hash sullo stesso sottoinsieme. Per risolvere questo problema, utilizzare una funzione HMAC con una chiave segreta.

Ricordate, se non avete motivi veri di prestazioni per la necessità di aggiungere complessità - non