Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Allow custom cipher and decipher functions #23

Open
wants to merge 13 commits into
base: next
Choose a base branch
from
Open
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ _Tip: place the middleware as low as you need cleartext data._

_Any middleware registered after field encryption will receive encrypted data for the selected fields._

### 2. Setup your encryption key
### 2. Setup your configuration

You can use two distinct configuration setups. The first is using encryption key and the other way is using your own encrypt/decript functions and logic:

> ⚠️ **Both ways are mutually exclusive, so using one of the configurations prevents you from using the other.**

#### 2.1. Using encryption key

Generate an encryption key:

Expand Down Expand Up @@ -79,6 +85,47 @@ client.$use(

_Tip: a key provided in code will take precedence over a key from the environment._

> ⚠️ **When using this method you will not be able to perform queries using encrypted fields.**

#### 2.2. Using your own encrypt/decript functions

Using your own functions is useful when you want full control over the cryptograph logic or whe you want to **perform queries over encrypted fields**, since you can use some static encryption algorithm. as static encryptions always generate the same hash for similar texts, you can encrypt the search field before performing the query.

First of all you must define your encryp/decrypt functions and pass then directly in the middleware config.

The following example shows using the native nodejs crypto module to perform encryption and decryption:

```ts
import crypto from 'crypto'

function cipher(decrypted: unknown): string {
const cipher = crypto.createCipheriv(
'aes-256-gcm',
process.env.CRYPTO_SALT,
process.env.CRYPTO_IV
)
return cipher.update(decrypted, 'utf-8', 'hex')
}

function decipher(encrypted: string): unknown {
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
process.env.CRYPTO_SALT,
process.env.CRYPTO_IV
)
return decipher.update(encrypted, 'hex', 'utf-8')
}

client.$use(
fieldEncryptionMiddleware({
encryptFn: (decrypted: unknown) => cipher(decrypted),
decryptFn: (encrypted: string) => decipher(encrypted)
})
)
```

> _Note: a valid encrypt function must always receive a value(it can be any valid DB data) and return a encrypted string. The opposite is valid for the decryption function._

### 3. Annotate your schema

In your Prisma schema, add `/// @encrypted` to the fields you want to encrypt:
Expand Down
15 changes: 7 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
{
"name": "prisma-field-encryption",
"version": "0.0.0-semantically-released",
"description": "Transparent field-level encryption at rest for Prisma",
"name": "prisma-custom-field-encryption",
"version": "0.0.1",
"description": "Transparent and customizable field-level encryption at rest for Prisma",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
"bin": {
"prisma-field-encryption": "./dist/generator/main.js"
"prisma-custom-field-encryption": "./dist/generator/main.js"
},
"author": {
"name": "François Best",
"email": "[email protected]",
"url": "https://francoisbest.com"
"name": "Victor Rodrigues",
"email": "[email protected]"
},
"repository": {
"type": "git",
"url": "https://github.com/47ng/prisma-field-encryption"
"url": "https://github.com/Vitu-77/prisma-field-encryption"
},
"keywords": [
"prisma",
Expand Down
Loading