Node.js Encryption

Now that the Virtru SDK knows you’re Alice, you can protect your first piece of data.

Encryption Basics

Before calling encrypt, you need to specify a few simple parameters.

You don’t need to include your email address when encrypting. You will already have access to anything you encrypt because you authenticated. But if you want anyone else to have access (like another one of your emails, [email protected]), you could include them here:

  // specify access controls
  const policy = new Virtru.PolicyBuilder()
    .addUsersWithAccess(["[email protected]"])
    .build();

  // protect & output
  const encryptParams = new Virtru.EncryptParamsBuilder()
    .withFileSource(unprotectedFile)
    .withDisplayFilename(unprotectedFile)
    .withPolicy(policy)
    .build();

Call encrypt and check out the resulting file:

  const protectedStream = await client.encrypt(encryptParams);
  let protectedExt = ".tdf.html"; // HTML format
  const protectedFile = unprotectedFile + protectedExt;
  await protectedStream
    .toFile(protectedFile)
    .then(() => console.log(`Encrypted file ${protectedFile}`));

Here's the complete source code:

// Encryption example - HTML format
const Virtru = require("virtru-sdk");

function loadVirtruClient() {
  const email = process.env.VIRTRU_SDK_EMAIL;
  const appId = process.env.VIRTRU_SDK_APP_ID;
  if (!email || !appId) {
    throw "An environment variable is not set:\n- VIRTRU_SDK_EMAIL\n- VIRTRU_SDK_APP_ID";
  }
  return new Virtru.Client({ email, appId });
}

async function protect(unprotectedFile) {
  const client = loadVirtruClient();

  // specify access controls
  const policy = new Virtru.PolicyBuilder()
    .addUsersWithAccess(["[email protected]"])
    .build();

  // protect & output
  const encryptParams = new Virtru.EncryptParamsBuilder()
    .withFileSource(unprotectedFile)
    .withDisplayFilename(unprotectedFile)
    .withPolicy(policy)
    .build();
  const protectedStream = await client.encrypt(encryptParams);
  let protectedExt = ".tdf.html"; // HTML format
  const protectedFile = unprotectedFile + protectedExt;
  await protectedStream
    .toFile(protectedFile)
    .then(() => console.log(`Encrypted file ${protectedFile}`));
}

// optionally execute from command line
if (require.main === module) {
  const unprotectedFile = "sensitive.txt";
  protect(unprotectedFile);
}
node protect-html.js

Now, your sensitive data is safe. Keep reading to see how or access your data by decrypting.


Encryption Lifecycle

That one little encrypt call did a lot of work behind the scenes to keep your sensitive data safe:

Protecting a file and sending the policy and key materials to VirtruProtecting a file and sending the policy and key materials to Virtru

Protecting a file and sending the policy and key materials to Virtru

  • Step 1: Your app authenticates with Virtru's entity service.

    This was when you proved you were [email protected].

  • Step 2: Then, an encrypt call protects any given data as ciphertext. This ciphertext is local to where encrypt was called (a browser, end user device, or server). Although encrypt uses the open Trusted Data Format (TDF), you can save the ciphertext in a file format that you can open anywhere—HTML.

    This was when your sensitive data became protected.

  • Step 3: While an encrypt call keeps the protected data as local ciphertext, a secure decryption key travels back to Virtru’s key server for safe-keeping. But this key server doesn’t hand out keys to anyone…

    This is why you don’t have to manage keys yourself.

  • Step 4: While an encrypt call keeps the protected data as local ciphertext, the SDK saves the access controls for the protected data in Virtru’s access server. The access server determines if a particular authenticated user (Step 1) can access protected data (Step 2) using a decryption key (Step 3).

    This is the crucial backend you don’t have to build or host. It never has access to your local data.


Encrypted File Formats

We generated a .tdf.html file above. This is the SDK default, but not the only option.

HTML FormatZIP Format
File Extension.tdf.html.tdf
File SizeFile sizes less than 100 MBAny file size
DecryptionAny Virtru SDKAny Virtru SDK
User ExperienceOpen file anywhere to redirect to Virtru's Secure ReaderDrag & drop in Virtru's Secure Reader

If you need a protected ZIP file, add it to the encrypt params and set the file extension:

// Encryption example - ZIP format
const Virtru = require("virtru-sdk");

function loadVirtruClient() {
  const email = process.env.VIRTRU_SDK_EMAIL;
  const appId = process.env.VIRTRU_SDK_APP_ID;
  if (!email || !appId) {
    throw "An environment variable is not set:\n- VIRTRU_SDK_EMAIL\n- VIRTRU_SDK_APP_ID";
  }
  return new Virtru.Client({ email, appId });
}

async function protect(unprotectedFile) {
  const client = loadVirtruClient();

  // specify access controls
  const policy = new Virtru.PolicyBuilder()
    .addUsersWithAccess(["[email protected]"])
    .build();

  // protect & output
  const encryptParams = new Virtru.EncryptParamsBuilder()
    .withFileSource(unprotectedFile)
    .withZipFormat() // ZIP format
    .withDisplayFilename(unprotectedFile)
    .withPolicy(policy)
    .build();
  const protectedStream = await client.encrypt(encryptParams);
  let protectedExt = ".tdf"; // ZIP format
  const protectedFile = unprotectedFile + protectedExt;
  await protectedStream
    .toFile(protectedFile)
    .then(() => console.log(`Encrypted file ${protectedFile}`));
}

// optionally execute from command line
if (require.main === module) {
  const unprotectedFile = "sensitive.txt";
  protect(unprotectedFile);
}
node protect-zip.js

And you’ll have a ZIP file with the same level of protection as HTML, but the caveats in the table above.


Did this page help you?