Skip to content

Releases: boringnode/encryption

Security hardening

Choose a tag to compare

@RomainLanz RomainLanz released this 10 Jul 07:04
v1.0.1
6bf7f15

This patch release strengthens ciphertext and signed-message validation while preserving support for existing valid encrypted values.

Security

  • Enforce full-length AES-GCM authentication tags and canonical nonce sizes.
  • Bind new AES-GCM and ChaCha20-Poly1305 ciphertexts to their algorithm and encrypter ID using HKDF-derived keys.
  • Reject non-canonical Base64URL values and encrypted payloads containing unexpected segments.
  • Reject empty or insecure MessageVerifier secrets.

Fixes

  • Throw an explicit error when configuring an empty key list.
  • Throw an explicit error when requesting an unknown encrypter.
  • Update base64UrlDecode types to correctly expose its nullable result.

Compatibility

Existing valid AES-GCM, ChaCha20-Poly1305, AES-CBC, AES-SIV, and signed-message values remain readable, including purpose-bound values and values encrypted before key rotation.

New AES-GCM and ChaCha20-Poly1305 ciphertexts use the v1: marker. During rolling deployments, update all readers before allowing updated instances to produce new ciphertexts, since previous library versions cannot read the new format.

Malformed payloads and configurations using secrets shorter than 16 characters are now intentionally rejected.

Commits

  • style: fix linting error (d8b90ea)
  • fix: harden message verification (dfc7eac)
  • fix: reject malformed encoded payloads (eab450c)
  • fix: harden authenticated encryption drivers (820b5b8)
  • chore: add minimal age gate (540376d)
  • chore(deps): update dependency release-it to v20 (#39) (66f4278)
  • chore(deps): update all non-major dependencies (#41) (de16b98)
  • chore(deps): update all non-major dependencies (#40) (a1dd3fb)
  • chore(deps): update all non-major dependencies (#38) (55e9496)
  • chore(deps): update all non-major dependencies (#36) (7da8bfe)
  • chore(deps): update dependency eslint to v10 (#34) (a2ccb17)
  • fix(deps): update all non-major dependencies (#33) (40368c7)
  • chore(deps): update dependency c8 to v11 (#35) (d29d73b)
  • fix: throw explicit error when using unknown encrypter (4b8ae55)
  • fix: validate non-empty key arrays and add regression tests (5e226bd)
  • docs(readme): update branch name (6b0814f)

Deterministic Encryption & Blind Indexes

Choose a tag to compare

@RomainLanz RomainLanz released this 06 Feb 21:59
v1.0.0
a3e22db

This release introduces first-class support for deterministic encryption and blind indexes, and hardens token parsing by validating encrypter IDs.

Breaking Changes

The driver contract now requires custom drivers to implement:

  • blindIndex(payload, purpose): string
  • blindIndexes(payload, purpose): string[]

If you maintain custom drivers, update them to match the new interface before upgrading.

New Features

Deterministic Encryption (AES-SIV)

This release introduces deterministic encryption through a new AES-SIV driver, designed for equality lookups on encrypted values.

import { Encryption } from '@boringnode/encryption'
import { aessiv } from '@boringnode/encryption/drivers/aes_siv'

const encryption = new Encryption(
  aessiv({
    id: 'users_email',
    key: process.env.APP_KEY!,
  })
)

You can then query deterministically encrypted values directly:

SELECT id, email_encrypted
FROM users
WHERE email_encrypted = :encrypted_email;

Blind Indexes

This release also adds blind index APIs across drivers, Encryption, and EncryptionManager, so you can perform equality lookups with dedicated index values, including key-rotation-friendly IN queries.

const indexes = encryption.blindIndexes('foo@example.com', 'users.email')
SELECT id, email_encrypted
FROM users
WHERE email_bidx IN (:idx1, :idx2, :idx3);

Bug Fixes

Encrypter IDs are now validated to prevent parsing ambiguity in ciphertext tokens:

  • id must be non-empty
  • id cannot contain .

Invalid IDs now fail fast with E_INVALID_ENCRYPTER_ID.

Simplify encrypt() API with options object

Choose a tag to compare

@RomainLanz RomainLanz released this 17 Jan 14:22
v0.2.5
a851c3f

New Features

Options object for encrypt method

The encrypt method now accepts an optional object as its second parameter, making it easier to specify only the options you need without passing undefined for unused parameters.

// Before: had to pass undefined to set only purpose
encryption.encrypt(data, undefined, 'password-reset')

// After: use options object
encryption.encrypt(data, { purpose: 'password-reset' })

Available options:

  • expiresIn - TTL for the encrypted value (e.g., '1h', '30m', 7200)
  • purpose - Purpose-bound encryption identifier

Examples:

// Only purpose
encryption.encrypt(data, { purpose: 'email-verification' })

// Only expiration
encryption.encrypt(data, { expiresIn: '24h' })

// Both options
encryption.encrypt(data, { expiresIn: '1h', purpose: 'password-reset' })

Backward Compatibility

The previous positional arguments syntax remains fully supported:

// Still works
encryption.encrypt(data, '1h', 'purpose')
encryption.encrypt(data, undefined, 'purpose')

Type Export

The new EncryptOptions type is exported for TypeScript users:

import type { EncryptOptions } from '@boringnode/encryption/types'

Build files before releasing and fix EncryptionConfig import in factory

Choose a tag to compare

@thetutlage thetutlage released this 07 Jan 06:21
473c545
  • fix: EncryptionConfig import in factory file (9af4138)
  • chore: build before publishing (9df2d00)
  • chore(release): 0.2.3 (1dd28e3)
  • fix(deps): update all non-major dependencies (#29) (76747c7)
  • chore(deps): update dependency @japa/runner to v5 (#30) (4b1c95d)
  • Accept keys as a Secret object (#31) (920d38f)

Full Changelog: 0.2.3...v0.2.4

Accept keys as Secret object

Choose a tag to compare

@thetutlage thetutlage released this 07 Jan 06:10
1dd28e3

What's Changed

  • Accept keys as a Secret object by @thetutlage in #31
  • chore(deps): update dependency @japa/runner to v5 by @renovate[bot] in #30
  • fix(deps): update all non-major dependencies by @renovate[bot] in #29

New Contributors

Full Changelog: v0.2.2...0.2.3

Publish proper files

Choose a tag to compare

@RomainLanz RomainLanz released this 13 Dec 10:47
v0.2.2
7693885

Seems that release-it hasn't build properly latest release

Export encryption class

Choose a tag to compare

@RomainLanz RomainLanz released this 13 Dec 10:39
v0.2.1
3605dfa

Commits

  • chore: export encryption class (770fe62)

Full Changelog: v0.2.0...v0.2.1

Restructure multi-key support with Encryption wrapper class

Choose a tag to compare

@RomainLanz RomainLanz released this 13 Dec 10:30
v0.2.0
d15dd81

Commits

  • chore(deps): update all non-major dependencies (#28) (7437620)
  • refactor!: restructure multi-key support with Encryption wrapper class (39e8812)
  • chore(deps): update all non-major dependencies (#27) (f3fbdfc)
  • chore(deps): update all non-major dependencies (#26) (16a2609)

What's Changed

  • chore(deps): update all non-major dependencies by @renovate[bot] in #26
  • chore(deps): update all non-major dependencies by @renovate[bot] in #27
  • chore(deps): update all non-major dependencies by @renovate[bot] in #28

Full Changelog: v0.1.0...v0.2.0

First usable release

Choose a tag to compare

@RomainLanz RomainLanz released this 11 Nov 21:40
v0.1.0
ef5099d

What's Changed

  • fix(deps): update all non-major dependencies by @renovate[bot] in #13
  • chore(deps): update all non-major dependencies by @renovate[bot] in #14
  • chore(deps): update all non-major dependencies by @renovate[bot] in #15
  • chore(deps): update all non-major dependencies by @renovate[bot] in #16
  • fix(deps): update all non-major dependencies by @renovate[bot] in #17
  • chore(deps): update all non-major dependencies by @renovate[bot] in #18
  • chore(deps): update all non-major dependencies by @renovate[bot] in #19
  • chore(deps): update dependency del-cli to v7 by @renovate[bot] in #20
  • chore(deps): update all non-major dependencies by @renovate[bot] in #21
  • chore(deps): update all non-major dependencies by @renovate[bot] in #22
  • chore(deps): update all non-major dependencies by @renovate[bot] in #23
  • chore(deps): update dependency eslint to ^9.39.0 by @renovate[bot] in #24
  • chore(deps): update all non-major dependencies by @renovate[bot] in #25

Commits

  • fix: add factories to tsup entry (2530530)
  • feat: add factory for easier testing (ec3ba90)
  • chore(deps): update all non-major dependencies (#25) (1513e2a)
  • chore: add more export for easy driver creation (182025b)
  • chore: update @poppinss/utils (3312e21)
  • chore: remove legacy driver (b3e329b)
  • chore(deps): update dependency eslint to ^9.39.0 (#24) (e5a0956)
  • chore(deps): update all non-major dependencies (#23) (50948a6)
  • chore(deps): update all non-major dependencies (#22) (33d0558)
  • chore(deps): update all non-major dependencies (#21) (1295323)
  • chore: update package exports (21caf60)
  • refactor: use internal base64 utils (21e7678)
  • style: fix imports (4a1c1d7)
  • chore: use @poppinss/ts-exec instead of ts-node (a39de48)
  • chore(deps): update dependency del-cli to v7 (#20) (ae93819)
  • chore(deps): update all non-major dependencies (#19) (95c1626)
  • chore(deps): update all non-major dependencies (#18) (c5f151a)
  • fix(deps): update all non-major dependencies (#17) (944c4a7)
  • chore(deps): update all non-major dependencies (#16) (e2e4fcb)
  • chore(deps): update all non-major dependencies (#15) (34b85d0)
  • chore(deps): update all non-major dependencies (#14) (77edc5a)
  • refactor(aes_256_cbc): pass the buffer directly (57e7ca5)
  • chore: update underlying dependencies (0f1b3c2)
  • fix: change imports to use .ts extension (e904a24)
  • test(manager): unskip test (ffa1b3c)
  • fix(deps): update all non-major dependencies (#13) (a4873de)

Full Changelog: v0.0.2...v0.1.0

Correct Exports

Choose a tag to compare

@RomainLanz RomainLanz released this 13 Jun 19:02
v0.0.2
18fd0d4

Commits

Full Changelog: v0.0.1...v0.0.2