Skip to content

Commit

Permalink
feat: remove crypto-js in favour of crypto native dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
fenos committed Jul 23, 2024
1 parent b548ed1 commit 7fe8c82
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 37 deletions.
24 changes: 0 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
"axios-retry": "^3.9.1",
"connection-string": "^4.3.6",
"conventional-changelog-conventionalcommits": "^5.0.0",
"crypto-js": "^4.2.0",
"dotenv": "^16.0.0",
"fastify": "^4.8.1",
"fastify-metrics": "^10.2.0",
Expand All @@ -81,7 +80,6 @@
"devDependencies": {
"@types/async-retry": "^1.4.5",
"@types/busboy": "^1.3.0",
"@types/crypto-js": "^4.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.2.1",
"@types/js-yaml": "^4.0.5",
Expand Down
54 changes: 43 additions & 11 deletions src/internal/auth/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
import AES from 'crypto-js/aes'
import Utf8 from 'crypto-js/enc-utf8'
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'crypto'
import { getConfig } from '../../config'

const { encryptionKey } = getConfig()

/**
* Decrypts a text with the configured encryption key via ENCRYPTION_KEY env
* @param ciphertext
*/
* Generate CryptoJs.AES key from passphrase
* https://github.com/brix/crypto-js/issues/468
* */
function convertPassphraseToAesKeyBuffer(key: string, salt: Buffer): Buffer {
const password = Buffer.concat([Buffer.from(key, 'binary'), salt])
const hash: Buffer[] = []
let digest = password
for (let i = 0; i < 3; i++) {
hash[i] = createHash('md5').update(digest).digest()
digest = Buffer.concat([hash[i]!, password])
}
return Buffer.concat(hash)
}

/**
* Replicate CryptoJs.AES.decrypt method
* */
export function decrypt(ciphertext: string): string {
return AES.decrypt(ciphertext, encryptionKey).toString(Utf8)
try {
const cipherBuffer = Buffer.from(ciphertext, 'base64')
const salt = cipherBuffer.subarray(8, 16)
const keyDerivation = convertPassphraseToAesKeyBuffer(encryptionKey, salt)
const [key, iv] = [keyDerivation.subarray(0, 32), keyDerivation.subarray(32)]
const contents = cipherBuffer.subarray(16)
const decipher = createDecipheriv('aes-256-cbc', key, iv)
const decrypted = Buffer.concat([decipher.update(contents), decipher.final()])
return decrypted.toString('utf8')
} catch (e) {
throw e
}
}

/**
* Encrypts a text with the configured encryption key via ENCRYPTION_KEY env
* @param plaintext
*/
* Replicate CryptoJs.AES.encrypt method
* */
export function encrypt(plaintext: string): string {
return AES.encrypt(plaintext, encryptionKey).toString()
try {
const salt = randomBytes(8)
const keyDerivation = convertPassphraseToAesKeyBuffer(encryptionKey, salt)
const [key, iv] = [keyDerivation.subarray(0, 32), keyDerivation.subarray(32)]
const cipher = createCipheriv('aes-256-cbc', key, iv)
const contents = Buffer.concat([cipher.update(plaintext), cipher.final()])
const encrypted = Buffer.concat([Buffer.from('Salted__', 'utf8'), salt, contents])
return encrypted.toString('base64')
} catch (e) {
throw e
}
}

0 comments on commit 7fe8c82

Please sign in to comment.