问题
I have encountered a great issue while using Laravel's datatables. I have a model that has 3 values automatically encrypted (using Crypt) by setter/getter.
I am using datatables to render a table by doing so:
return datatables()->of(Patient::query())
->addColumn('name_surname', function($row){
return $row->name.' '.$row->surname;
})
->make(true);
There is 3 ways to pass a model to datatable:
- by query (Patient::query())
- by collection (Patient::all())
- by DB facade
The third doesnt decrypt data. The query is ultrafast but doesnt allow searching through data Collection allows on everything but it's ultra slow. (5-7 seconds / table draw). I also tried caching it but it didnt bring any help to this to my suprise
How can I possibly search through encrypted data without causing performance to drop so low?
Btw. That's the Trait im using for setter encryption and getter decryption
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (in_array($key, $this->encryptable)) {
$value = Crypt::decrypt($value);
} return $value;
}
public function setAttribute($key, $value)
{
if (in_array($key, $this->encryptable)) {
$value = Crypt::encrypt($value);
}
return parent::setAttribute($key, $value);
}
回答1:
Update (2019-06-02): There's a standalone library that implements this, called CipherSweet. Additionally, a Laravel adapter is in the works.
This has been answered in a blog post titled (appropriately), Building Searchable Encrypted Databases with PHP and SQL. You can expand upon its contents by asking yourself the following questions:
- How sensitive is the data I'm encryptiong?
- People's lives could be severely affected if it was compromised: Use a KDF for the blind index.
- Not very: Use HMAC for the blind index.
- Do we want only exact matches in the SELECT query, or are collisions tolerable provided they aren't too numerous?
- No collisions ever: Use the full KDF/HMAC output.
- Collisions OK: Truncate (which saves on storage), use as a Bloom filter.
Once you have these questions answered, you're going to make sure your encryption provides ciphertext integrity (e.g. libsodium's crypto_secretbox()
with a random nonce per message), and you're going to use HMAC/PBKDF2 with a different key to generate a blind index of the plaintext to store alongside the ciphertext (i.e. separate column).
Instead of querying for the ciphertext, just rebuild the blind index then decrypt the results. This gives you a fast, reliable search operation while still offering semantically-secure data encryption.
来源:https://stackoverflow.com/questions/47912168/laravel-with-datatables-searching-encrypted-data