Securing Data in Electron Apps, Part 1

Trevor Foskett
Feb 27 · 4 min read

Adding Encryption to Electron with the Virtru Node SDK

Image for post
Image for post
Photo by Raphaël Biscaldi on Unsplash

As someone who considers himself a bit of a novice coder, I’ve always found the combined simplicity & power of the Electron framework to be really attractive. Writing desktop apps in nothing but JavaScript, HTML, and CSS means I can start moving my projects out of the browser, off the command line, and into standalone, user-friendly (and demo-friendly!) applications. And since the Virtru SDK is available in NodeJS, I figured it would be relatively easy to integrate into an Electron app (spoiler: it was). Finally, with a large open-source community, there’s no shortage of sample projects to work off or potential integrations to try.

Quick Links

While this project can be expanded in many different directions, I decided to start simple: a desktop application that encrypts and decrypts files based on user input and interaction. Unlike my Node command line encryption project, this project will let users select files from the native file dialog and save to the location of their choice.

Building It

  1. Get a simple Electron UI running.
  2. Get the native file menu to display after clicking a “Select File” button.
  3. Pull in data from selected file.
  4. Encrypt selected file with the Virtru SDK.
  5. Add additional user controls for sharing, expiration, watermarking, and disabling of re-sharing.
  6. Add advanced settings page to allow users to update credentials and specify save location.

Getting the initial base app running is easy — just follow along with Electron’s “First App” guide and you’ve already got an application with its own window running. I just needed to add my own basic HTML to the index.html file to render Virtru’s logo and a “Select File(s) button. Step 1 done!

main.js — Quickstart Electron code to generate the app & a window.

Next, the button hast to actually perform an action. To do this, we need communication between Electron’s main thread, main.js — responsible for creating browser windows and interacting with your OS and the renderer process, renderer.js — running code within those browser windows generated by the main process. A full breakdown of how these interact is found here. For the purpose of my application, it’s a simple communication: upon button click in the renderer process, send a message to the main process to open a native file dialog to select a file. Electron comes equipped with functionality for both of these already. The ipcRenderer module can exchange messages with the main thread, and the dialog module opens system-native dialogs and menus. Part 2 in the bag.

The dialog module also helps us pass in the full path of any selected files, meaning we’re not restricted to pulling from one predefined “input folder” as was the case in my previous projects. We can then pass that path information to any function in our app to act on that file. Easy win on step 3.

renderer.js — Button click sends event to main thread.
main.js — Main thread registers the button click event and opens the file dialog to select filepaths.

At this point, I added the Virtru SDK to encrypt the selected file(s).

main.js — Pass selected files to Virtru encrypt function.

Now for the bells and whistles. As with my Google Doc encryption project, I added toggles for the user to add security controls to each file; these settings are then used to construct the policy object that will dictate how other users interact with this protected content. Since the policy is created in the main thread, the user selections need to be communicated from the renderer process:

renderer.js — Send user inputs to main thread.

The main process then updates the policy with those settings:

main.js — Construct policy object based on inputs received from renderer.

That takes care of most of the functionality we need, but in order to make this easier to use for others, I wanted to add a few more things:

  • Decryption functionality
  • Settings page

The decrypt functionality was really easy to add after completing all of the above work; I used the same mechanism for opening a file dialog and operating on the selected file, this time simply with a decrypt function rather than encrypt. On a decrypt operation, there’s no need to input any policy settings, so there’s no additional work.

I wanted to add a settings page so that users wouldn’t have to open up some obscure file in order to add or update their Virtru AppID. I added another button that triggers a new BrowserWindow object in the main thread that will open with its own settings.html file to render my settings page.

main.js — Create a new window to show the settings page.

On this page I included three user input fields: email address, appId, and a save location for encrypted or decrypted files. I used Cameron Nokes’ example to create a simple data store object where those values are stored and read.

Image for post
Image for post
The finished product.
Image for post
Image for post
Settings page.

Conclusion

Virtru Technology Blog

Building developer tools in the interest of data protection…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store