I need to use db_query() to fetch information from the database.

I had originally thought that I could encrypt the value I need and then use that encrypted value in my db_query(). Seems things aren't that straight forward.

What's the correct way of doing this? Is it possible?

CommentFileSizeAuthor
#11 field_encrypt_hmac_settings.patch6.01 KBgMaximus
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gMaximus created an issue. See original summary.

rlhawk’s picture

Status: Active » Postponed (maintainer needs more info)

I'm not clear on what you're trying to do. Please provide more information.

gMaximus’s picture

I'm writing a custom module that in itself isn't much use to anyone else. I'm receiving data via a JSON end point. I need to use that data to lookup existing entities.

I've encrypted fields on my custom entity types because it is things like name (text field), email (email module), address (Address module)and a telephone number (phone module).

Usually I use db_query() to look up things in my module. However, when the field is encrypted, db_query() becomes useless due to the encryption.

So I wondered if there was a way to achieve what I need. To have encrypted fields whilst still being able to look up entities.

I hope that clarifies things.

Many thanks

rlhawk’s picture

There's no easy way to search for an encrypted value in a database query. One possible method would be to generate a hash of the original data and store that somewhere; then when you need to perform the query, you search for the hash. That has significant security implications, though, so it would not be appropriate for many situations.

gMaximus’s picture

I'm considering using field_encrypt_views_filters module to create a view with some contextual filters.

Then call views_get_view_result() and pass in my un-encrypted values as arguments.

What's your thoughts on that approach?

rlhawk’s picture

I'm not familiar with that module. I'd be concerned about performance and security, so take a look at the code and see exactly how it works, then give it a try.

gMaximus’s picture

Yes. My two concerns as well. It works by storing decrypted values in temporary tables. I don't know much about temporary tables and if they are at risk to thieves?

I feel stuck. I need to protect my customers data but I also need to be able to look things up in the database. I just hadn't anticipated this.

Surely others must have similar use cases to me. I feel like I'm missing something. Perhaps I'm not approaching this use case correctly?

rlhawk’s picture

Here's a good article about how to think about, and solve, this problem:

https://paragonie.com/blog/2017/05/building-searchable-encrypted-databas...

gMaximus’s picture

Would using drupal_hmac_base64($data, $key) be fine from a security point of view? My understanding is that you can't decrypt it?

I'm extending the field_encrypt module to do this. Seems the most logical place. If the above is fine for security, I'm pretty much ready to provide a patch.

I plan to use the key module to store the HMAC key offsite.

gMaximus’s picture

Project: Encrypt » Field Encryption
Version: 7.x-2.3 » 8.x-2.x-dev

Moving over to field_encrypt issue queue. That is where this functionality will logically need to live.

gMaximus’s picture

Version: 8.x-2.x-dev » 7.x-1.0-beta3
FileSize
6.01 KB

Well I believe that using HMAC is fine in terms of security because it isn't designed to be decrypted.

Attached is a patch that extends the field_encrypt module to also store a hash for the value that has been encrypted.

I then added a settings page for the module. It allows us to select a "Encrypt" configuration for encrypting a field. It then allows us to select a key provided by the key module for the HMAC value. I wanted this configuration so I could use offsite key management for the HMAC key. Whilst also being able to choose a specific "Encrypt" configuration for the field encryption.

This allows us to perform exact match queries to the database. To do so, here is a sample of code I'm using:

$key_id = variable_get('field_encrypt_hmac_key');
$key = key_get_key_value($key_id);
$first_name = drupal_hmac_base64('Guy', $key);
$customer_id = db_query("SELECT c.id 
      FROM {eck_customer} c
      LEFT JOIN {field_data_field_customer_first_name} first_name ON c.id = first_name.entity_id
      WHERE first_name.field_customer_first_name_value_hmac = :first_name
      AND type = 'customer'", array(':first_name' => $first_name))->fetchField();
  if ($customer_id) {
    return $customer_id;
     }

Before applying this patch, you will need to decrypt all your encrypted fields. Apply the patch and flush the cache to access the settings page. Select the your key and configuration. Then go back and encrypt your fields.

Above all, please backup your database to be safe.

gMaximus’s picture

Status: Postponed (maintainer needs more info) » Needs review
gMaximus’s picture

Title: db_query() and encrypt(); How can I use them together? » Select config settings form & HMAC values for querying the DB
andrea.cavattoni’s picture

Patch is working but needs documentation and you must check of the existance of key module before doing anything.