Шифрование файла узла приводит к пустому файлу для определенных типов файлов - PullRequest
0 голосов
/ 08 марта 2020

При шифровании файлов определенных типов создается пустой (0B) зашифрованный файл. Я могу воспроизвести эту ошибку с помощью PDF-файлов и JPG-файлов, однако этот код работает для шифрования текстовых файлов и некоторых исполняемых файлов, поэтому проблема не только в открытом тексте. Я исчерпал все возможности, которые могу придумать. У кого-нибудь есть идеи?

Вот ссылка на суть с минимальным воспроизведением ошибки. Вот встроенная копия кода:

const fs = require("fs");
const crypto = require("crypto");

/**
 * Returns a SHA512 digest to be used as the key for AES encryption. Uses a 64 byte salt with 10,000 iterations of PBKDF2
 * Follows the NIST standards described here: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
 * @param  {Buffer} salt          16 byte random salt
 * @param  {string} encryptionKey User's entered encryption key
 * @return {Buffer}               SHA512 hash that will be used as the IV.
 */
function createDerivedKey(salt, encryptionKey) {
    return crypto.pbkdf2Sync(
        encryptionKey,
        salt,
        (iterations = 10000),
        (keylen = 32),
        (digest = "sha512")
    );
}

/**
 * Encrypts a file using this format:
 * (https://gist.github.com/AndiDittrich/4629e7db04819244e843)
 * +--------------------+-----------------------+----------------+----------------+
 * | Salt               | Initialization Vector | Auth Tag       | Payload        |
 * | Used to derive key | AES GCM XOR Init      | Data Integrity | Encrypted File |
 * | 64 Bytes, random   | 16 Bytes, random      | 16 Bytes       | (N-96) Bytes   |
 * +--------------------+-----------------------+----------------+----------------+
 *
 * A huge thank you to: https://medium.com/@brandonstilson/lets-encrypt-files-with-node-85037bea8c0e
 *
 * @param  {String} filePath      Absolute path of unencrypted file.
 * @param  {String} encryptionKey User verified encryption key.
 * @return {String}               Absolute path of encrypted file.
 */
function encryptFile(filePath, encryptionKey) {
    console.log(`Encrypting ${filePath} with key: ${encryptionKey}`);

    // Create cipher
    const salt = crypto.randomBytes(64);
    const derivedKey = createDerivedKey(salt, encryptionKey);
    const initializationVector = crypto.randomBytes(16);
    let cipher = crypto.createCipheriv(
        "aes-256-gcm",
        derivedKey,
        initializationVector
    );

    let encryptedFilePath = `${filePath}.qlock`;
    let write = fs.createWriteStream(encryptedFilePath);

    let encryptBlob = fs
        .createReadStream(filePath)
        .pipe(cipher)
        .on("finish", () => {
            encryptBlob
                .pipe(write)
                .on("error", () => { console.log("Write error.")});
        });

    return encryptedFilePath;
}

/**************
 * Entry Points
 **************/

/**
 * QuickLock file encryption process.
 * @param  {String} filePath         Absolute path of file.
 * @param  {String} encryptionPhrase Passphrase for encryption that has been verified by the user already in the GUI.
 * @return {String}                  Absolute path of encrypted file.
 */
function onFileEncryptRequest(filePath, encryptionPhrase) {
    let encryptedFilePath = encryptFile(filePath, encryptionPhrase);
    console.log(`Encrypted file: ${encryptedFilePath}`);
    return encryptedFilePath;
}

function testing_main() {
    // let file = "failure.jpg";
    // let file = "failure.pdf";
    // let file = "success.txt";

    let encryptedFilePath = onFileEncryptRequest(
        file,
        "test"
    )
}

testing_main();
...