安全地搜索加密的数据库字段

安全地搜索加密的数据库字段

Ruby 数据库驱动器

访问GitHub主页

共273Star

详细介绍

Blind Index

Securely search encrypted database fields

Designed for use with attr_encrypted

Build Status

How It Works

This project uses this approach by Scott Arciszewski. To summarize, we compute a keyed hash of the sensitive data and store it in a column. To query, we apply the keyed hash function (PBKDF2-HMAC-SHA256) to the value we’re searching and then perform a database search. This results in performant queries for equality operations, while keeping the data secure from those without the key.

Getting Started

Add these lines to your application’s Gemfile:

gem 'attr_encrypted'
gem 'blind_index'

Add columns for the encrypted data and the blind index

# encrypted data
add_column :users, :encrypted_email, :text
add_column :users, :encrypted_email_iv, :text

# blind index
add_column :users, :encrypted_email_bidx, :text
add_index :users, :encrypted_email_bidx

Generate one key for encryption and one key for hashing and set them in your environment (dotenv is great for this). For development, you can use these:

EMAIL_ENCRYPTION_KEY=00000000000000000000000000000000
EMAIL_BLIND_INDEX_KEY=99999999999999999999999999999999

And add to your model

class User < ApplicationRecord
  attr_encrypted :email, key: ENV["EMAIL_ENCRYPTION_KEY"]

  blind_index :email, key: ENV["EMAIL_BLIND_INDEX_KEY"]
end

And query away

User.where(email: "test@example.org")

Validations

To prevent duplicates, use:

class User < ApplicationRecord
  validates :email, uniqueness: true
end

We also recommend adding a unique index to the blind index column through a database migration.

Expressions

You can apply expressions to attributes before indexing and searching. This gives you the the ability to perform case-insensitive searches and more.

class User < ApplicationRecord
  blind_index :email, expression: -> (v) { v.downcase } ...
end

Multiple Indexes

You may want multiple blind indexes for an attribute. To do this, add another column:

add_column :users, :encrypted_email_ci_bidx, :text
add_index :users, :encrypted_email_ci_bidx

And update your model

class User < ApplicationRecord
  blind_index :email, ...
  blind_index :email_ci, attribute: :email, expression: -> (v) { v.downcase } ...
end

Search with:

User.where(email_ci: "test@example.org")

Key Stretching

Key stretching increases the amount of time required to compute hashes, which slows down brute-force attacks. You can set the number of iterations with:

class User < ApplicationRecord
  blind_index :email, iterations: 1000000, ...
end

The default is 10000. Changing this value requires you to recompute the blind index.

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help: