diff --git a/package.json b/package.json index 907b11b..b642c1a 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "body-parser-xml": "^2.0.3", "connect-datadog-graphql": "^0.0.12", "cors": "^2.8.5", - "cryptr": "^4.0.2", + "cryptr": "^6.4.0", "db-migrate": "^0.11.13", "db-migrate-pg": "^1.2.2", "envalid": "^5.0.0", diff --git a/src/lib/crypt.ts b/src/lib/crypt.ts index 1da1e84..717bf38 100644 --- a/src/lib/crypt.ts +++ b/src/lib/crypt.ts @@ -1,5 +1,34 @@ +import crypto from 'crypto'; import cryptr from 'cryptr'; import config from '../config'; -export const crypt = new cryptr(config.applicationSecret); +// Decrypts ciphertexts produced by cryptr v4 (aes-256-ctr + SHA-256 key). +// Kept so existing DB credentials and client tokens remain readable after the +// cryptr v6 upgrade, until Phase 2 (DB re-encryption) is complete. +function decryptV4(value: string): string { + const key = crypto + .createHash('sha256') + .update(config.applicationSecret) + .digest(); + const iv = Buffer.from(value.slice(0, 32), 'hex'); + const encrypted = value.slice(32); + const decipher = crypto.createDecipheriv('aes-256-ctr', key, iv); + return decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8'); +} + +const cryptV6 = new cryptr(config.applicationSecret); + +export const crypt = { + encrypt: (value: string) => cryptV6.encrypt(value), + decrypt: (value: string): string => { + try { + return cryptV6.decrypt(value); + } catch (err: any) { + if (err?.message?.includes('unable to authenticate data')) { + throw err; + } + return decryptV4(value); + } + }, +}; diff --git a/yarn.lock b/yarn.lock index f6ebc6a..51fabbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2921,9 +2921,10 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -cryptr@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cryptr/-/cryptr-4.0.2.tgz#8a93b5ca7667d1a6131e396bab23a134ff1f5dc6" +cryptr@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/cryptr/-/cryptr-6.4.0.tgz#a5f49b77679d411ceeb6cbf0acd51a94f3d050a9" + integrity sha512-9jpMU9HMt1vhMUqNO+MPuGEpbh/f7HHZdxrd6L2DMwTuYGyt9pgUJfQyTS1Ei4/sn7qPM4FkjxUoiW79k0x8sA== currently-unhandled@^0.4.1: version "0.4.1"