Skip to content

Instantly share code, notes, and snippets.

@Abhinav1217
Created June 2, 2024 19:54
Show Gist options
  • Save Abhinav1217/ad6796b9f56616ddb668c1d10151f62e to your computer and use it in GitHub Desktop.
Save Abhinav1217/ad6796b9f56616ddb668c1d10151f62e to your computer and use it in GitHub Desktop.
A collection of utility functions for cryptographic operations using Node.js's built-in crypto module.
/**
* CryptoUtil.ts
*
* A collection of utility functions for cryptographic operations using Node.js's built-in crypto module.
*
* Attribution: Utilizes Node.js's native crypto module for cryptographic operations.
*
* ## Contents:
* - `sha256(message)`: Creates a SHA-256 hash of the input message.
* - `generateRandomBytes(count)`: Generates a specified number of random bytes.
* - `hmacSignature(message, secret)`: Creates an HMAC signature of the input message using a shared secret key.
* - `aes256CbcEncrypt(plaintext, secretKey, iv)`: Encrypts a message using AES-256-CBC.
* - `aes256CbcDecrypt(ciphertext, secretKey, iv)`: Decrypts a message using AES-256-CBC.
* - `md5Hash(str)`: Computes the MD5 hash of a given string.
* - `sha1Hash(str)`: Computes the SHA-1 hash of a given string.
* - `blowfishHash(str)`: Computes the Blowfish hash of a given string.
* - `generateSecretKeyAndIvFromPassphrase(passphrase)`: Generates a secret key and IV bytes from a passphrase, making it more secure.
*/
import * as crypto from 'node:crypto';
/**
* Creates a SHA-256 hash of the input message.
*
* @param {string} message - The message to hash.
* @returns {Promise<string>} A promise that resolves to the SHA-256 hash of the message.
*/
export async function sha256(message: string): Promise<string> {
return new Promise((resolve, reject) => {
crypto.createHash('sha256').update(message).digest('hex', (err: any, digest: string | PromiseLike<string>) => {
if (err) reject(err);
else resolve(digest);
});
});
}
/**
* Generates a specified number of random bytes.
*
* @param {number} count - The number of random bytes to generate.
* @returns {Promise<Buffer>} A promise that resolves to a Buffer containing the specified number of random bytes.
*/
export async function generateRandomBytes(count: number): Promise<Buffer> {
return new Promise((resolve, reject) => {
crypto.randomBytes(count, (err, buffer) => {
if (err) reject(err);
else resolve(buffer);
});
});
}
/**
* Creates an HMAC signature of the input message using a shared secret key.
*
* @param {string} message - The message to sign.
* @param {string} secret - The shared secret key.
* @returns {Promise<string>} A promise that resolves to the HMAC signature of the message.
*/
export async function hmacSignature(message: string, secret: string): Promise<string> {
return new Promise((resolve, reject) => {
crypto.createHmac('sha256', secret)
.update(message)
.digest('hex', (err: any, digest: string | PromiseLike<string>) => {
if (err) reject(err);
else resolve(digest); // Correctly handling the digest result
});
});
}
/**
* Encrypts a message using AES-256-CBC.
*
* @param {string} plaintext - The plaintext message to encrypt.
* @param {string} secretKey - The secret key for encryption.
* @param {string} iv - The initialization vector for encryption.
* @returns {Promise<string>} A promise that resolves to the encrypted ciphertext.
*/
export async function aes256CbcEncrypt(plaintext: string, secretKey: string, iv: string): Promise<string> {
return new Promise((resolve, reject) => {
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secretKey), Buffer.from(iv, 'hex'));
let encrypted = '';
cipher.on('readable', () => {
const chunk = cipher.read();
if (chunk) encrypted += chunk.toString('hex');
});
cipher.on('end', () => resolve(encrypted));
cipher.write(Buffer.from(plaintext, 'utf8'));
cipher.end();
});
}
/**
* Decrypts a message using AES-256-CBC.
*
* @param {string} ciphertext - The ciphertext message to decrypt.
* @param {string} secretKey - The secret key for decryption.
* @param {string} iv - The initialization vector for decryption.
* @returns {Promise<string>} A promise that resolves to the decrypted plaintext.
*/
export async function aes256CbcDecrypt(ciphertext: string, secretKey: string, iv: string): Promise<string> {
return new Promise((resolve, reject) => {
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(secretKey), Buffer.from(iv, 'hex'));
let decrypted = '';
decipher.on('readable', () => {
const chunk = decipher.read();
if (chunk) decrypted += chunk.toString('utf8');
});
decipher.on('end', () => resolve(decrypted));
decipher.write(Buffer.from(ciphertext, 'hex'));
decipher.end();
});
}
/**
* Computes the MD5 hash of a given string.
*
* @param {string} str - The input string to hash.
* @returns {string} The MD5 hash of the input string.
*/
export async function md5Hash(str: string): Promise<string> {
return new Promise((resolve, reject) => {
crypto.createHash('md5').update(str).digest('hex', (err: any, digest: string | PromiseLike<string>) => {
if (err) reject(err);
else resolve(digest);
});
});
}
/**
* Computes the SHA-1 hash of a given string.
*
* @param {string} str - The input string to hash.
* @returns {string} The SHA-1 hash of the input string.
*/
export async function sha1Hash(str: string): Promise<string> {
return new Promise((resolve, reject) => {
crypto.createHash('sha1').update(str).digest('hex', (err: any, digest: string | PromiseLike<string>) => {
if (err) reject(err);
else resolve(digest);
});
});
}
/**
* Computes the Blowfish hash of a given string.
*
* @param {string} str - The input string to hash.
* @returns {Promise<string>} A promise that resolves to the Blowfish hash of the input string.
*/
export async function blowfishHash(str: string): Promise<string> {
return new Promise((resolve, reject) => {
crypto.pbkdf2(str, 'salt', 1000, 64, 'sha512', (err, derivedKey) => {
if (err) reject(err);
else resolve(derivedKey.toString('hex'));
});
});
}
/**
* Generates a secret key and IV bytes from a passphrase, making it more secure.
*
* @param {string} passphrase - The passphrase to derive the secret key and IV from.
* @returns {Promise<{secretKey: Buffer, iv: Buffer}>} A promise that resolves to an object containing the derived secret key and IV.
*/
export async function generateSecretKeyAndIvFromPassphrase(passphrase: string): Promise<{secretKey: Buffer, iv: Buffer}> {
return new Promise( (resolve, reject) => {
try {
const salt = crypto.randomBytes(16);
const keyMaterial = crypto.scrypt(passphrase, salt, 32);
const secretKey = keyMaterial.slice(0, 32);
const iv = keyMaterial.slice(32);
resolve({secretKey, iv});
} catch (error) {
reject(error);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment