Protect.js supports searching encrypted data, which enabled trusted data access so that you can:
- Prove to your customers that you can track exactly what data is being accessed in your application.
- Provide evidence for compliance requirements, such as SOC2 and BDSG.
The best way to describe searchable encryption is with an example. Let's say you have a table of users in your database, and you want to search for a user by their email address:
# SELECT * FROM users WHERE email = '[email protected]';
id | name | email
----+----------------+----------------------------
1 | Alice Johnson | alice.johnson@example.com
Whether you executed this query directly in the database, or through an application ORM, you'd expect the result to be the same.
But what if the email address is encrypted before it's stored in the database?
Executing the following query will return all the rows in the table with the encrypted email address:
# SELECT * FROM users;
id | name | email
----+----------------+----------------------------
1 | Alice Johnson | mBbKmsMMkbKBSN...
2 | Jane Doe | s1THy_NfQdN892...
3 | Bob Smith | 892!dercydsd0s...
Now, what's the issue if you execute the equality query with this data set?
# SELECT * FROM users WHERE email = '[email protected]';
id | name | email
----+----------------+----------------------------
There would be no results returned, because [email protected]
does not equal mBbKmsMMkbKBSN...
!
There is prior art for this, and it's called Homomorphic Encryption, and is defined as:
"a form of encryption that allows computations to be performed on encrypted data without first having to decrypt it"
The issue with homomorphic encryption isn't around the functionality, but rather performance in a modern application use case.
CipherStash's approach to searchable encryption solves the performance problem without sacrificing security, usability, or functionality.
CipherStash uses EQL to perform queries on encrypted data, and Protect.js makes it easy to use EQL with any TypeScipt application.
// 1) Encrypt the search term
const searchTerm = '[email protected]'
const encryptedParam = await protectClient.encrypt(searchTerm, {
column: protectedUsers.email, // Your Protect column definition
table: protectedUsers, // Reference to the table schema
})
if (encryptedParam.failure) {
// Handle the failure
}
// 2) Build an equality query using EQL
const equalitySQL = `
SELECT email
FROM users
WHERE cs_unique_v1($1) = cs_unique_v1($2)
`
// 3) Execute the query, passing in the Postgres column name
// and the encrypted search term as the second parameter
// (client is an arbitrary Postgres client)
const result = await client.query(equalitySQL, [ protectedUser.email.getName(), encryptedParam.data ])
Using the above approach, Protect.js is generating the EQL payloads and which means you never have to drop down to writing complex SQL queries.
So does this solve the original problem of searching on encrypted data?
# SELECT * FROM users WHERE WHERE cs_unique_v1(email) = cs_unique_v1(eql_payload_created_by_protect);
id | name | email
----+----------------+----------------------------
1 | Alice Johnson | mBbKmsMMkbKBSN...
The answer is yes! And you can use Protect.js to decrypt the results in your application.
Based on some benchmarks CipherStash's approach is 410,000x faster than homomorphic encryption:
Operation | Homomorphic | CipherStash | Speedup |
---|---|---|---|
Encrypt | 1.97 ms | 48 µs | ~41× |
a == b | 111 ms | 238 ns | ~466 000× |
a > b | 192 ms | 238 ns | ~807 000× |
a < b | 190 ms | 240 ns | ~792 000× |
a >= a | 44 ms | 221 ns | ~199 000× |
a <= a | 44 ms | 226 ns | ~195 000× |
Every single decryption event is logged in CipherStash ZeroKMS, giving you an audit trail of data access events to help you prove compliance with your data protection policies.
With searchable encryption, you can:
- Prove to your customers that you can track exactly what data is being accessed in your application.
- Provide evidence for compliance requirements, such as SOC2 and BDSG.
With searchable encryption:
- Data can be encrypted, stored, and searched in your existing PostgreSQL database.
- Encrypted data can be searched using equality, free text search, and range queries.
- Data remains encrypted, and will be decrypted using the Protect.js library in your application.
- Queries are blazing fast, and won't slow down your application experience.
- Every decryption event is logged, giving you an audit trail of data access events.
Read more about the implementation details to get started.