yarle-evernote-to-md
Version:
Yet Another Rope Ladder from Evernote
86 lines • 3.64 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.performDecryption = void 0;
var CryptoJS = require("crypto-js");
const crypto = __importStar(require("crypto"));
const base64 = __importStar(require("base64-js"));
// PBKDF2 implementation (modified for SHA256 support)
function pbkdf2(password, salt, iterations, keyLength) {
return crypto.pbkdf2Sync(password, salt, iterations, keyLength, 'sha256');
}
// HMAC implementation
function hmacSHA256(key, data) {
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
return hmac.digest();
}
// AES decryption
function decryptAES(ciphertext, key, iv) {
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
let decrypted = decipher.update(ciphertext);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted;
}
const extractDataFromEncryptedByteArray = (data) => {
const START_INDEX = 4;
const TWO_BYTES = 16;
const START_SALTHMAC = START_INDEX + TWO_BYTES;
const START_IV = START_SALTHMAC + TWO_BYTES;
const START_CIPHERTEXT = START_IV + TWO_BYTES;
const FOUR_END_BYTES = -32;
return {
salt: data.subarray(START_INDEX, START_SALTHMAC),
saltHmac: data.subarray(START_SALTHMAC, START_IV),
iv: data.subarray(START_IV, START_CIPHERTEXT),
cipherText: data.subarray(START_CIPHERTEXT, FOUR_END_BYTES),
body: data.subarray(0, FOUR_END_BYTES),
bodyHmac: data.subarray(FOUR_END_BYTES)
};
};
const performDecryption = (encryptedText, passwords) => {
try {
const encryptedDataByteArr = base64.toByteArray(encryptedText);
const encryptedData = extractDataFromEncryptedByteArray(encryptedDataByteArr);
// Use the password to generate a digest for the encrypted body
// If it matches the existing digest, assume the password is correct
for (const password of passwords) {
const keyhmac = pbkdf2(password, encryptedData.saltHmac, 50000, 16);
const testhmac = hmacSHA256(keyhmac, encryptedData.body);
const matchHmac = crypto.timingSafeEqual(testhmac, encryptedData.bodyHmac);
if (matchHmac) {
const key = pbkdf2(password, encryptedData.salt, 50000, 16);
const decrypted = decryptAES(encryptedData.cipherText, key, encryptedData.iv);
return decrypted.toString();
}
}
}
catch (e) {
console.log(e.message);
}
return encryptedText;
};
exports.performDecryption = performDecryption;
//# sourceMappingURL=decrypt.js.map