Skip to content

Commit 7fe8c82

Browse files
committed
feat: remove crypto-js in favour of crypto native dependency
1 parent b548ed1 commit 7fe8c82

File tree

3 files changed

+43
-37
lines changed

3 files changed

+43
-37
lines changed

package-lock.json

-24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
"axios-retry": "^3.9.1",
5555
"connection-string": "^4.3.6",
5656
"conventional-changelog-conventionalcommits": "^5.0.0",
57-
"crypto-js": "^4.2.0",
5857
"dotenv": "^16.0.0",
5958
"fastify": "^4.8.1",
6059
"fastify-metrics": "^10.2.0",
@@ -81,7 +80,6 @@
8180
"devDependencies": {
8281
"@types/async-retry": "^1.4.5",
8382
"@types/busboy": "^1.3.0",
84-
"@types/crypto-js": "^4.1.1",
8583
"@types/fs-extra": "^9.0.13",
8684
"@types/jest": "^29.2.1",
8785
"@types/js-yaml": "^4.0.5",

src/internal/auth/crypto.ts

+43-11
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,53 @@
1-
import AES from 'crypto-js/aes'
2-
import Utf8 from 'crypto-js/enc-utf8'
1+
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'crypto'
32
import { getConfig } from '../../config'
4-
53
const { encryptionKey } = getConfig()
64

75
/**
8-
* Decrypts a text with the configured encryption key via ENCRYPTION_KEY env
9-
* @param ciphertext
10-
*/
6+
* Generate CryptoJs.AES key from passphrase
7+
* https://github.com/brix/crypto-js/issues/468
8+
* */
9+
function convertPassphraseToAesKeyBuffer(key: string, salt: Buffer): Buffer {
10+
const password = Buffer.concat([Buffer.from(key, 'binary'), salt])
11+
const hash: Buffer[] = []
12+
let digest = password
13+
for (let i = 0; i < 3; i++) {
14+
hash[i] = createHash('md5').update(digest).digest()
15+
digest = Buffer.concat([hash[i]!, password])
16+
}
17+
return Buffer.concat(hash)
18+
}
19+
20+
/**
21+
* Replicate CryptoJs.AES.decrypt method
22+
* */
1123
export function decrypt(ciphertext: string): string {
12-
return AES.decrypt(ciphertext, encryptionKey).toString(Utf8)
24+
try {
25+
const cipherBuffer = Buffer.from(ciphertext, 'base64')
26+
const salt = cipherBuffer.subarray(8, 16)
27+
const keyDerivation = convertPassphraseToAesKeyBuffer(encryptionKey, salt)
28+
const [key, iv] = [keyDerivation.subarray(0, 32), keyDerivation.subarray(32)]
29+
const contents = cipherBuffer.subarray(16)
30+
const decipher = createDecipheriv('aes-256-cbc', key, iv)
31+
const decrypted = Buffer.concat([decipher.update(contents), decipher.final()])
32+
return decrypted.toString('utf8')
33+
} catch (e) {
34+
throw e
35+
}
1336
}
1437

1538
/**
16-
* Encrypts a text with the configured encryption key via ENCRYPTION_KEY env
17-
* @param plaintext
18-
*/
39+
* Replicate CryptoJs.AES.encrypt method
40+
* */
1941
export function encrypt(plaintext: string): string {
20-
return AES.encrypt(plaintext, encryptionKey).toString()
42+
try {
43+
const salt = randomBytes(8)
44+
const keyDerivation = convertPassphraseToAesKeyBuffer(encryptionKey, salt)
45+
const [key, iv] = [keyDerivation.subarray(0, 32), keyDerivation.subarray(32)]
46+
const cipher = createCipheriv('aes-256-cbc', key, iv)
47+
const contents = Buffer.concat([cipher.update(plaintext), cipher.final()])
48+
const encrypted = Buffer.concat([Buffer.from('Salted__', 'utf8'), salt, contents])
49+
return encrypted.toString('base64')
50+
} catch (e) {
51+
throw e
52+
}
2153
}

0 commit comments

Comments
 (0)