Use cases

  • Password based encryption of a file
  • Previously shared common secret (password)

node version

  • 8.11.2

JavaScript Version

  • ECMAScript 6 and higher

Installation

  • crypto is is a native node module, no installation is required
  • Winston logger

Example Code for JavaScript Password based symmetric file encryption using AES-GCM and PBKDF2

/**
 * An example for synchronous encryption and decryption of a file
 * with node fileStreams featuring:
 * - an out of the box working Example
 * - generation of a random password
 * - derivation of a key from a password
 * - base64 Encoding of byte arrays
 * - Utf8 Encoding of Plaintext
 * - Logging of exceptions
 */

var crypto = require("crypto"),
  fs = require("fs"),
  winston = require("winston");

const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.splat(),
    winston.format.simple()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.simple(),
      handleExceptions: true
    })
  ]
});

const demonstrateFileEncryption = () => {
  try {
    // the password used for derviation of a key, assign your password here
    // if none is assigned a random one is generated
    let password = null;
    if (password === null) {
      password = crypto.randomBytes(48).toString("utf8");
    }

    // derive key with password and salt
    // keylength adheres to the "ECRYPT-CSA Recommendations" on "www.keylength.com"
    let salt = crypto.randomBytes(128);
    let derivedKey = crypto.pbkdf2Sync(password, salt, 10000, 32, "sha256");

    // create random initialization vector
    let iv = crypto.randomBytes(16);

    // read and ENCRYPT the filecontent and write it to a encrypted file
    let inputFile = fs.readFileSync("file.txt");
    let cipher = crypto.createCipheriv("aes-256-gcm", derivedKey, iv);
    let encrypted = cipher.update(inputFile, "utf8", "base64");
    encrypted += cipher.final("base64");
    let authTag = cipher.getAuthTag();
    fs.writeFileSync("file.enc.txt", Buffer.from(encrypted, "base64"));

    // DECRYPT the filecontent and write it to a decrypted file
    let decipher = crypto.createDecipheriv("aes-256-gcm", derivedKey, iv);
    decipher.setAuthTag(authTag);
    let decrypted = decipher.update(encrypted, "base64", "utf8");
    decrypted += decipher.final("utf8");
    decrypted = Buffer.from(decrypted, "utf8");
    fs.writeFileSync("file.dec.txt", decrypted);

    logger.info(
      "Decrypted file content and original file content are the same: %s",
      Buffer.compare(decrypted, inputFile) === 0 ? "yes" : "no"
    );
  } catch (error) {
    logger.error(error.message);
  }
};

demonstrateFileEncryption();

// for unit testing purposes
module.exports = { demonstrateFileEncryption, logger };

References

Authors

Tobias Hirzel

Reviews