I use encryption in my app but to the cost of lesser indexing capability. You can index a HMAC-Sha digest of the value. The HMAC-Sha is a hash algorithm that also takes an encryption key. To get the correct digest ýou must know the value and the key. But it wont work with ranges or substring matches - just exact matches.
Example:
var KEY = "secret"; // Have somewhere in a module or so.
function encrypt(obj, key) {
// TODO implement using webCrypto or similar
}
function hmacSHA(prop, key) {
// TODO implement using webCrypto or similar
}
function User(name, age) {
this.data = encrypt({name: name, age: age}, KEY);
this.nameIndex = hmacSHA(name, KEY);
}
// Store user
db.users.put(new User("Foo", 42));
// Find user by name. Need to know the exact name:
var user = yield db.users.where('nameIndex').equals(hmacSHA("Foo", KEY)).first();
Note though, that the index can make the data subject to replay attacks, so if you should be able to index the data you will loose some security value. But sometimes you need to take the least bad of two things...
For example, even without the key, it would be possible to see if two users have the same name. You can't know the name but the index is the same. Also, if an attacker has extremely good hardware and knows a name of a particular user, she could brute force attack the database to find out the key. That would require lots and lots of hardware if key is 128 bit, if at all possible. But in theory, with government hardware, it could be.