4

I have set up attr_encrypted in my app with individual 'iv's for every record.

# Fields
User.e_name
User.e_name_iv

I am trying to search the User table for a known name. I've tried:

User.find_by_name("Joe Bloggs") # undefined method "find_by_name" for Class
User.where("name = ?", "Joe Bloggs").first # column "name" does not exist
User.where(:e_name => User.encrypt_name("Joe Bloggs"))  # must specify an iv

How can I find a record by its name?

sscirrus
  • 55,407
  • 41
  • 135
  • 228
  • 1
    You'll have to weaken your encryption (use the same IV for all records, for example). When encrypting fields (passwords, etc.), you set up per-record iv/salt __precisely__ to disable any kind of mass queries. – Sergio Tulentsev Aug 04 '17 at 07:15
  • 1
    The `:single_iv_and_salt` mode is deprecated and will be removed, though. So, I guess, your two choices are: don't encrypt or don't query. – Sergio Tulentsev Aug 04 '17 at 07:18
  • An alternative is to filter in the application (this is obviously very slow and wastes a ton of resources) – Sergio Tulentsev Aug 04 '17 at 07:20
  • @SergioTulentsev Well that's a pain. What do you think of storing a hash of the values in another column and comparing a search term to the hash (akin to logging in with a password)? – sscirrus Aug 04 '17 at 07:35
  • I'm no security expert, but this looks like a workable compromise. – Sergio Tulentsev Aug 04 '17 at 07:45
  • This does weaken the security somewhat. But increases usability. Balancing the two is an art :) – Sergio Tulentsev Aug 04 '17 at 07:47
  • @sscirrus You can't search by password when the password is hashed. Proper password hashing algorithms like BCrypt produce an output that contains a salt and a completely different hash, even with the same input password. This is analogous to your problem of each record having a different initialization vector. – user229044 Dec 17 '18 at 03:59

1 Answers1

2

While it is possible to do some searching, it's not very practical. you'll have to potentially iterate through every record trying each respective IV until you have an exact match, depending on the number of records you have this will not be very practical.

Have you read the readme? https://github.com/attr-encrypted/attr_encrypted#things-to-consider-before-using-attr_encrypted

Searching, joining, etc

While choosing to encrypt at the attribute level is the most secure solution, it is not without drawbacks. Namely, you cannot search the encrypted data, and because you can't search it, you can't index it either. You also can't use joins on the encrypted data. Data that is securely encrypted is effectively noise. So any operations that rely on the data not being noise will not work. If you need to do any of the aforementioned operations, please consider using database and file system encryption along with transport encryption as it moves through your stack.

MZaragoza
  • 10,108
  • 9
  • 71
  • 116