UNPKG

authy-extractor

Version:

Extract 2FA tokens from Authy

57 lines (56 loc) 2.74 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_forge_1 = __importDefault(require("node-forge")); // Got following functions from service workers function isBase32(value) { return value.replace(/-|\s/g, '').match(/^[a-zA-Z2-7]+=*$/) !== null; } function generatePBKDF2Key(password, salt, options) { // eslint-disable-next-line no-param-reassign if (options.decodeSalt) salt = node_forge_1.default.util.hexToBytes(salt); if (options.withoutEncoding) { return node_forge_1.default.pkcs5.pbkdf2(password, salt, options.iterations, options.keySize); } return node_forge_1.default.pkcs5.pbkdf2(unescape(encodeURIComponent(password)), salt, options.iterations, options.keySize); } function decryptAESWithKey(key, value) { const ivBuffer = node_forge_1.default.util.createBuffer(node_forge_1.default.util.decodeUtf8('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')); const keyBuffer = node_forge_1.default.util.createBuffer(key); const valueBuffer = node_forge_1.default.util.createBuffer(node_forge_1.default.util.decode64(value)); // forge.aes is deprecated, changed to forge.cipher.createDecipher // const decryptionCypher = forge.aes.createDecryptionCipher(keyBuffer, "CBC"); // decryptionCypher.start(ivBuffer); // decryptionCypher.update(valueBuffer); // return decryptionCypher.finish() ? decryptionCypher.output.data : null; const decipher = node_forge_1.default.cipher.createDecipher('AES-CBC', keyBuffer); decipher.start({ iv: ivBuffer }); decipher.update(valueBuffer); return decipher.finish() ? decipher.output.data : null; } function decryptAES(salt, password, value, withoutEncoding = false) { const pbkdf2Key = generatePBKDF2Key(password, salt, { iterations: 1000, keySize: 32, decodeSalt: false, withoutEncoding, }); return decryptAESWithKey(pbkdf2Key, value); } function decryptTokens(tokens, password) { return tokens.reduce((decryptedTokens, token) => { let decrypted = decryptAES(token.salt, password, token.encrypted_seed, false); if (decrypted === null || !isBase32(decrypted)) { decrypted = decryptAES(token.salt, password, token.encrypted_seed, true); if (decrypted === null || !isBase32(decrypted)) { return decryptedTokens; } } decryptedTokens.push(Object.assign(Object.assign({}, token), { decrypted_seed: decrypted })); return decryptedTokens; }, []); } exports.default = decryptTokens;