Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
encrypt(data, password) {
// generate a random key and IV
// Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256
// forge uses Fortuna as its pseudorandom number generator, mentioned at the following link
// https://www.npmjs.com/package/node-forge#prng
// Ehe seed is added with extra randomness collected from the user, e.g. mouse movement
this.iv = forge.random.getBytesSync(12);
// alternatively, generate a password-based 16-byte key
this.salt = forge.random.getBytesSync(128);
const key = forge.pkcs5.pbkdf2(password, this.salt, 10, 16); // numIterations set to 10
// encrypt some bytes using GCM mode
// (other modes include: CBC, ECB, CFB, OFB, CTR)
// Note: CBC and ECB modes use PKCS#7 padding as default
const cipher = forge.cipher.createCipher(setting.cipherMode, key);
cipher.start({ iv: this.iv });
cipher.update(forge.util.createBuffer(data));
cipher.finish();
const encrypted = cipher.output;
this.tag = cipher.mode.tag;
// outputs encrypted hex
// console.log(encrypted.toHex());
return encrypted;
}
if (!opts.passPhrase || opts.passPhrase.length < 20) {
throw new Error('passPhrase must be least 20 characters')
}
if (opts.dek.keyLength < NIST.minKeyLength) {
throw new Error(`dek.keyLength must be least ${NIST.minKeyLength} bytes`)
}
if (opts.dek.salt.length < NIST.minSaltLength) {
throw new Error(`dek.saltLength must be least ${NIST.minSaltLength} bytes`)
}
if (opts.dek.iterationCount < NIST.minIterationCount) {
throw new Error(`dek.iterationCount must be least ${NIST.minIterationCount}`)
}
this.dek = opts.dek
// Create the derived encrypting key
let dek = forge.pkcs5.pbkdf2(
opts.passPhrase,
opts.dek.salt,
opts.dek.iterationCount,
opts.dek.keyLength,
opts.dek.hash)
dek = forge.util.bytesToHex(dek)
Object.defineProperty(this, '_', { value: () => dek })
// JS magick
this._getKeyInfo = this.findKeyByName = this._getKeyInfo.bind(this)
// Provide access to protected messages
this.cms = new CMS(this)
}
const derivePassword = (password, keySize = 32, iv = false) => {
// generate a random iv
let passwordIv;
if (iv) {
// turn existing iv into bytes
passwordIv = forge.util.hexToBytes(iv);
} else {
// generate a new random iv
passwordIv = forge.random.getBytesSync(keySize);
}
// amount of pbkdf2 iterations,
const iterations = 300000;
// derive a 16 bit key from the password and iv
const derivedBytes = forge.pkcs5.pbkdf2(password, passwordIv, iterations, keySize);
// turn derivedBytes into a readable string
const encryptionKey = forge.util.bytesToHex(derivedBytes);
// turn passwordIv into a readable string
const encryptionIv = forge.util.bytesToHex(passwordIv);
return {
key: encryptionKey,
iv: encryptionIv
};
};
__decryptData (cipherText, password) {
let derivedKey = forge.pkcs5.pbkdf2(password, this.otpSecret, this.iterations, this.keySize)
let decipher = forge.cipher.createDecipher('AES-CBC', derivedKey)
decipher.start({ iv: forge.util.decode64(this.otp) })
decipher.update(forge.util.createBuffer(forge.util.decode64(cipherText)))
decipher.finish()
return decipher.output.toString()
}
}
static keyFromPassword(password: string, salt: string) {
let keySize = 32;
return forge.pkcs5.pbkdf2(password, salt, 1000, keySize);
}
decryptData (cipherText, password) {
let derivedKey = forge.pkcs5.pbkdf2(password, this.otpSecret, this.interations, this.keySize)
let decipher = forge.cipher.createDecipher('AES-CBC', derivedKey)
decipher.start({ iv: forge.util.decode64(this.otp) })
decipher.update(forge.util.createBuffer(forge.util.decode64(cipherText)))
decipher.finish()
return decipher.output.toString()
}
return new Promise((resolve, reject) => {
forge.pkcs5.pbkdf2(password, salt, iterations, keySize, (err, key) =>
err ? reject(err) : resolve(key));
});
}
private decryptDataWithOtp(cipherText: string, password: string): string {
const decipher: forge.cipher.BlockCipher = forge.cipher.createDecipher(
"AES-CBC",
forge.pkcs5.pbkdf2(password, this.otpSecret, this.iterations, this.keySize),
);
decipher.start({ iv: forge.util.decode64(this.otp) });
decipher.update(forge.util.createBuffer(forge.util.decode64(cipherText)));
decipher.finish();
return decipher.output.toString();
}
}
public encrypt(message: string, password: string, address: string, iv: any) {
const derivedKey = forge.pkcs5.pbkdf2(password, address, this.interations, this.keySize);
const cipher = forge.cipher.createCipher('AES-CBC', derivedKey);
cipher.start({ iv: forge.util.decode64(iv) });
cipher.update(forge.util.createBuffer(message));
cipher.finish();
return forge.util.encode64(cipher.output.getBytes());
}