---
title: Querying encrypted data in Rails using Deterministic Encryption
teaser: |-
  Encrypting data is easy — querying it isn’t.
  Rails' deterministic encryption makes encrypted fields both searchable and secure.
tags: ruby,ruby on rails,security
author: Trésor Bireke
published_on: 2025-11-25
---

Encrypting data is straightforward in most Rails apps; however, once it's encrypted, querying it can be complex. Rails 7 introduced deterministic encryption, which addresses this problem by allowing you to query encrypted fields while still keeping data secure.

## What is Deterministic Encryption?

Deterministic encryption is an encryption method that produces the same ciphertext for identical plaintext inputs when using the same key.
This predictability enables querying encrypted data, unlike standard encryption, which produces different ciphertexts for the same input each time.

Why use Deterministic Encryption?

There are cases where you need to query encrypted data.
Here are some examples:

- Email lookups: Finding a user by their encrypted email address
- Social Security Numbers: Searching for records by encrypted SSN
- Phone numbers: Looking up customers by their encrypted contact information

With which standard (non-deterministic) encryption would these queries not be possible, since the same value encrypts differently each time.

## How to use Deterministic Encryption

Deterministic encryption can be set up for a Rails app in the following steps:

### 1. Configure Active Record Encryption

First, we need to ensure Active Record Encryption is configured in the application:

```ruby
# config/application.rb
config.active_record.encryption.primary_key = Rails.application.credentials.active_record_encryption[:primary_key]
config.active_record.encryption.deterministic_key = Rails.application.credentials.active_record_encryption[:deterministic_key]
config.active_record.encryption.key_derivation_salt = Rails.application.credentials.active_record_encryption[:key_derivation_salt]
```

Then we generate keys using:

```bash
rails db:encryption:init
```

### 2. Add Deterministic Encryption to a Model

We use the  `encrypts` method with the `deterministic: true` option:

```ruby
class User < ApplicationRecord
	encrypts :email, deterministic: true
	encrypts :ssn, deterministic: true
end
```

### 3. Query Encrypted Fields

Now you can query the encrypted fields just like regular fields:

```ruby

# Find user by encrypted email
user = User.find_by(email: "user@example.com")

# Search by encrypted SSN
user = User.where(ssn: "123-45-6789").first
```

Rails automatically handles the encryption during the query, making it seamless.

## Deterministic vs Non-Deterministic Encryption

### Deterministic Encryption:

- Same plaintext always produces the same ciphertext
- Allows querying and indexing
- Slightly less secure because patterns can be detected
- Best for fields you need to search on

### Non-Deterministic Encryption:

- Same plaintext produces a different ciphertext each time
- Cannot be queried or indexed
- More secure against pattern analysis
- Best for fields you only need to read/display

Example of using both:

```ruby
class User < ApplicationRecord
  encrypts :email, deterministic: true          # Searchable
  encrypts :credit_card_number                  # Not searchable, more secure
end
```

## Security Considerations

While deterministic encryption allows querying, there are important security tradeoffs to consider:

**When to Use Deterministic Encryption**:

- Fields that need to be searchable or indexed
- Data that doesn't reveal sensitive patterns when duplicated
- Applications where the convenience of querying outweighs the slightly reduced security

**When NOT to Use Deterministic Encryption**:

- Highly sensitive data like passwords (use proper password hashing instead)
- Data where pattern detection poses a significant risk
- Fields that don't need to be queried

## Conclusion

Deterministic encryption in Rails 8 provides a practical solution for encrypting sensitive data while maintaining the ability to query it.
This comes with some security trade-offs compared to non-deterministic encryption, but it's still very valuable for fields that need to be encrypted yet searchable.
