You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> `EncryptedString` type for Mongoose schemas. Provides AES-256-CBC encryption-at-rest for strings.
9
+
> `EncryptedString` type for Mongoose schemas. Provides AES-256-GCM and AES-256-CBC encryption-at-rest for strings.
10
+
11
+
**Note:** The AES-256-GCM algorithm provides an additional cryptographic tamper-safety of the encrypted data by adding an authTag and should be preferred over AES-256-CBC. See also the [migration guide](#migrating-from-aes-cbc-to-aes-gcm) if you are already using AES-256-CBC.
10
12
11
13
## Usage
12
14
@@ -27,32 +29,32 @@ Person = mongoose.model('Person', {
Directly querying the MongoDB will return the encrypted data.
41
+
Directly querying the MongoDB will return the encrypted data. With the default AES-256-GCM algorithm, each encrypted field is stored as a 3-part string (`iv|authTag|ciphertext`). AES-256-CBC produces a 2-part string (`iv|ciphertext`).
Registers the new type `EncryptedString` in the `mongoose` instance's schema types. Encryption/decryption is done with AES-256-CBC using the given `key`. After calling this funtion you can start using the new type via `mongoose.Schema.Types.EncryptedString` in your schemas.
57
+
Registers the new type `EncryptedString` in the `mongoose` instance's schema types. Encryption/decryption is done using the given `key` and `algorithm` (default: `aes-256-gcm`). After calling this function you can start using the new type via `mongoose.Schema.Types.EncryptedString` in your schemas.
56
58
57
59
#### mongoose
58
60
@@ -62,20 +64,24 @@ The mongoose instance where `EncryptedString` should be registered.
62
64
63
65
The key used for encryption/decryption. Length must be 32 bytes. See [notes](#notes) for details.
64
66
67
+
#### algorithm
68
+
69
+
Optional. The encryption algorithm to use. Accepted values: `aes-256-gcm`, `aes-256-cbc`. Default: `aes-256-gcm`. Throws an `Error` if an unsupported value is passed.
70
+
65
71
## Use with lean() queries
66
72
67
-
For performance reasons it maybe useful to use Mongoose's `lean()` queries. Doing so, the query will return the raw JSON objects from the MongoDB database where all properties of type `EncryptedString` are encrypted.
73
+
For performance reasons it may be useful to use Mongoose's `lean()` queries. Doing so, the query will return the raw JSON objects from the MongoDB database where all properties of type `EncryptedString` are encrypted.
68
74
69
75
To get the clear text values back you can directly use [@tsmx/string-crypto](https://www.npmjs.com/package/@tsmx/string-crypto) which is also used internally in this package for encryption and decryption.
70
76
71
77
```js
72
78
constkey='YOUR KEY HERE';
73
79
constsc=require('@tsmx/string-crypto');
74
80
75
-
// query raw objects with encrypted string values
81
+
// query raw objects with encrypted string values, either AES-256-GCM or AES-256-CBC
76
82
let person =awaitPerson.findOne({ id:'id-test' }).lean();
77
83
78
-
// decrypt using string-crypto
84
+
// decrypt using string-crypto (algorithm is detected automatically)
79
85
let firstName =sc.decrypt(person.firstName, { key: key });
80
86
let lastName =sc.decrypt(person.lastName, { key: key });
- a hexadecimal value of 64 characters length (= 32 bytes)
89
95
- Don't override getters/setter for `EncryptedString` class or schema elements of this type. This would break the encryption.
96
+
97
+
## Migrating from AES-CBC to AES-GCM
98
+
99
+
Switching the algorithm after data has already been stored will break decryption of existing documents. To safely migrate existing CBC-encrypted data to GCM, follow these steps:
100
+
101
+
1. Keep calling `registerEncryptedString(mongoose, key, 'aes-256-cbc')` until migration is complete.
102
+
2. Run a one-off migration script: query affected documents via `.lean()` to get raw encrypted values, then for each `EncryptedString` field decrypt with `sc.decrypt(value, { key })` and re-encrypt with `sc.encrypt(value, { key, algorithm: 'aes-256-gcm' })`, and write back using `collection.updateOne(...)` directly (bypassing Mongoose to avoid double-encryption).
103
+
3. Once all documents are migrated, switch to `registerEncryptedString(mongoose, key)` (GCM default).
0 commit comments