🕸️ refactor: Migrate from crypto to Web Crypto API (#3357)

* move crypto to async webcrypto

update encrypt/decrypt

forgot await

* chore: import order - openidStrategy.js

* chore: import order - Session.js

* chore: import order - AuthController.js

* Update AuthService.js

---------

Co-authored-by: Danny Avila <danacordially@gmail.com>
This commit is contained in:
matt burnett 2024-08-04 23:59:45 -04:00 committed by GitHub
parent b6fe7e5570
commit 3e0f95458f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 108 additions and 51 deletions

View file

@ -1,34 +1,74 @@
require('dotenv').config();
const crypto = require('crypto');
const { webcrypto } = require('node:crypto');
const key = Buffer.from(process.env.CREDS_KEY, 'hex');
const iv = Buffer.from(process.env.CREDS_IV, 'hex');
const algorithm = 'aes-256-cbc';
function encrypt(value) {
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(value, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
async function encrypt(value) {
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
'encrypt',
]);
const encoder = new TextEncoder();
const data = encoder.encode(value);
const encryptedBuffer = await webcrypto.subtle.encrypt(
{
name: algorithm,
iv: iv,
},
cryptoKey,
data,
);
return Buffer.from(encryptedBuffer).toString('hex');
}
function decrypt(encryptedValue) {
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encryptedValue, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
async function decrypt(encryptedValue) {
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
'decrypt',
]);
const encryptedBuffer = Buffer.from(encryptedValue, 'hex');
const decryptedBuffer = await webcrypto.subtle.decrypt(
{
name: algorithm,
iv: iv,
},
cryptoKey,
encryptedBuffer,
);
const decoder = new TextDecoder();
return decoder.decode(decryptedBuffer);
}
// Programatically generate iv
function encryptV2(value) {
const gen_iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, gen_iv);
let encrypted = cipher.update(value, 'utf8', 'hex');
encrypted += cipher.final('hex');
return gen_iv.toString('hex') + ':' + encrypted;
// Programmatically generate iv
async function encryptV2(value) {
const gen_iv = webcrypto.getRandomValues(new Uint8Array(16));
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
'encrypt',
]);
const encoder = new TextEncoder();
const data = encoder.encode(value);
const encryptedBuffer = await webcrypto.subtle.encrypt(
{
name: algorithm,
iv: gen_iv,
},
cryptoKey,
data,
);
return Buffer.from(gen_iv).toString('hex') + ':' + Buffer.from(encryptedBuffer).toString('hex');
}
function decryptV2(encryptedValue) {
async function decryptV2(encryptedValue) {
const parts = encryptedValue.split(':');
// Already decrypted from an earlier invocation
if (parts.length === 1) {
@ -36,10 +76,30 @@ function decryptV2(encryptedValue) {
}
const gen_iv = Buffer.from(parts.shift(), 'hex');
const encrypted = parts.join(':');
const decipher = crypto.createDecipheriv(algorithm, key, gen_iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
'decrypt',
]);
const encryptedBuffer = Buffer.from(encrypted, 'hex');
const decryptedBuffer = await webcrypto.subtle.decrypt(
{
name: algorithm,
iv: gen_iv,
},
cryptoKey,
encryptedBuffer,
);
const decoder = new TextDecoder();
return decoder.decode(decryptedBuffer);
}
module.exports = { encrypt, decrypt, encryptV2, decryptV2 };
async function hashToken(str) {
const data = new TextEncoder().encode(str);
const hashBuffer = await webcrypto.subtle.digest('SHA-256', data);
return Buffer.from(hashBuffer).toString('hex');
}
module.exports = { encrypt, decrypt, encryptV2, decryptV2, hashToken };