Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

attribute_queryable_encrypted

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

attribute_queryable_encrypted

  • 0.2.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

AttributeQueryableEncrypted

Assigns a digest-hashed value to an attribute writer using a portion of the value assigned to each attribute's normal writer. The digest-hashed prefix can then be used to identify other objects with the same prefix without revealing the underlying value.

AttributeQueryableEncrypted was inspried by shuber's excellent attr_encrypted gem, and aims for compatibility. It attempts to addresses a shortcoming of unsalted encryption, where encrypted columns are queryable, but attackable using a precomputed "rainbow table". By exposing only a portion of the unsalted encrypted data to precomputed attacks, AttributeQueryableEncrypted reduces the need for a full-table scan on encrypted data.

Selecting multiple candidates with matching prefix digests and subsequently decrypting the full salted/encrypted data field to find a exact match will reduce the need for a full table scan. You should use attr_encrypted, or your own crypto logic, to handle encrypting and decrypting the appropriate full data field.

Example:

class HiddenValue                                                              
  include AttributeQueryableEncrypted::PrefixAttributes                                                        
  attr_accessor :prefix_data_digest
  attribute_queryable_encrypted :data
  
  def data=(something)
    ...something fancy that obscures the data...
  end
end                                                                            
                                                                             
hider = HiddenValue.new                                                        
                                                                             
hider.data = "This is a string"                                                
hider.prefix_data_digest                                                       
  # => "a37010c994067764d86540bf479d93b4d0c3bb3955de7b61f951caf2fd0301b0"      

ActiveRecord:

ActiveRecord users gain a find_all_by_[prefix]_[attribute] query method for their prefix digest column:

  HiddenValue.find_all_by_prefix_data("This is ")
  # => [#<HiddenValue id: 1, encrypted_data: "MWE2ODg0ZTVmNTA2M2I3MTZmMWQxZGI3NzA0MjgyMzRj...", prefix_data_digest: "MTgyODBlMWFkNGZiMjAyZTc5Y2FiYTcxODZhYTg1OWM3OGNhOWI...">, #<HiddenValue id: 2, encrypted_data: "WQxZGI3NzANTA2M2I3MTZmMj0MjgyMzRMWE2ODg0ZTVm...", prefix_data_digest: "MTgyODBlMWFkNGZiMjAyZTc5Y2FiYTcxODZhYTg1OWM3OGNhOWI...">]

The returned records - a subset of the full table - can then be iterated over to find an exact match.

A convenience method is provided to do this for you - find_by_[attribute]. Note that it requires an attribute getter method (but not necessarily a database column) that provides a cleartext match for your query argument:

  HiddenValue.find_by_data("This is a string")
  # => #<HiddenValue id: 1, encrypted_data: "MWE2ODg0ZTVmNTA2M2I3MTZmMWQxZGI3NzA0MjgyMzRj...", prefix_data_digest: "MTgyODBlMWFkNGZiMjAyZTc5Y2FiYTcxODZhYTg1OWM3OGNhOWI...">

You'll need to create an appropriately-named prefix digest column on your own.

AttributeQueryableEncrypted is automatically included into ActiveRecord::Base when the gem is installed. To use, just specify the columns you want:

  class HiddenValue < ActiveRecord::Base
    attr_encrypted :data, :key => { |record| SiteKey + record.salt }
    attribute_queryable_encrypted :data, :length => "35%", :suffix => "queryable"
  end
  

Your :data accessor (provided here by attr_encrypted) should exist prior to defining the queryable accessor.

Options:

  • :length - an integer value length, or percentage expressed as a string ("72%"). Default is "50%".
  • :prefix - prefix name for the storage accessor. Default is "prefix"
  • :suffix - suffix name for the storage accessor. Default is "digest"
  • :encode - Base64 encode the digest hash, suitable for database persistence. Default is false.
  • :stretches - an integer number of iterations through the digest algorithm. More will reduce the ease of a precomputed attack. Default is 3.
  • :key - an optional key to salt the digest algorithm. Default is nil.
  • :digest - the Digest class to use. Must respond to #update. Default is Digest::SHA2.

If you choose to use :stretches and/or :key, you should keep their values secret.

Requirements:

  • Ruby >= 1.9
  • ActiveSupport >= 3.0
  • ActiveRecord >= 3.0 for ActiveRecord usage

Warnings

  • This technique is not without shortcomings, notably that the entire prefix digest is subject to a precomputed attack.
  • You should consider using secret values for :stretches and :key, and setting the :length option to a level that obscures an appropriate amount of your data without potentially giving away too much.
  • Increasing :stretches incurs a small performance penalty.
  • Decreasing :length can return more records in the initial matched set, potentially decreasing performance. Increasing :length makes more of the data subject to a precomputed attack.

(The MIT License)

© 2011 (Scott Burton, ChaiOne)

FAQs

Package last updated on 20 Jan 2012

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc