Skip to content

fix(security): repair encryption key derivation for aes-256-cbc - #4

Merged
merlik787-droi merged 1 commit into
mainfrom
fix/encryption-key-derivation
Oct 9, 2026
Merged

merlik787-droi merged 1 commit into
mainfrom
fix/encryption-key-derivation

Conversation

@merlik787-droi

Copy link
Copy Markdown
Contributor

Closes #3

Problem

aes-256-cbc needs a 32-byte key, but EncryptionService only normalized keys shorter than 32 characters. Keys of 32+ characters (the 41-char default fallback and the common 64-char hex key) were passed through unchanged, so createCipheriv threw Invalid key length — secret encryption/decryption was broken unless a 32-char key was configured. Production also silently used the known insecure default.

Changes

src/common/encryption.service.ts

  • normalizeKey(): any key whose length is not exactly 32 is digested with sha256(...).digest('hex').slice(0, 32). A raw 32-character key is still used verbatim, so existing ciphertext encrypted under a 32-char key keeps working.
  • The constructor now throws if NODE_ENV=production and ENCRYPTION_KEY is unset, instead of falling back to the insecure default.

test/encryption.service.spec.ts (new)

  • Round-trips for the default key and 32/40/64-char and short keys.
  • Asserts the production guard throws.

Verification (in microservices/config-service)

npm run lint:check    → clean
npm run format:check  → clean
npm run type-check    → clean
npm test              → 3 suites, 11 tests passed
npm run build         → nest build OK

aes-256-cbc needs an exactly-32-byte key, but the service only hashed
keys *shorter* than 32 characters. Any key of 32+ characters - including
the built-in default fallback (41 chars) and the common 64-char hex key -
was passed through unchanged and made createCipheriv throw 'Invalid key
length', so secret encryption/decryption was completely broken unless a
32-char key happened to be configured.

- Normalize any non-32-character key to a 32-byte hex key (keeps the raw
  key when it is exactly 32 chars, preserving existing ciphertext)
- Fail fast at startup when NODE_ENV=production and ENCRYPTION_KEY is unset
  instead of silently falling back to a known insecure default
- Add EncryptionService tests covering the default, 32/40/64-char and
  short keys plus the production guard
@merlik787-droi
merlik787-droi merged commit 76eb418 into main Oct 9, 2026
1 check passed
@merlik787-droi
merlik787-droi deleted the fix/encryption-key-derivation branch October 9, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security: encryption is broken for any key >= 32 chars (incl. default) - Invalid key length

2 participants