Private content on a statically-served site

Jun 1, 2014

Although most of my posts are meant for public consumption, there are a few that are a result of my thinking “out loud” or feeling the need to document something personal that happened to me. These few posts are for my eyes only. When your website is served by a scriptable webserver, you have the option of requiring HTTP authentication for certain webpages. This is not possible if your site is being served by S3 or Github pages. So how do you selectively keep content private on a public bucket? The same way you keep any of your data secure when there’s the risk of it being publicly visible: you encrypt it.

Have a look at this page. All you’ll see is a great big padlock icon. Click on it, and you’ll be prompted for a password. If you enter the correct password, the padlock icon will disappear and the content of the post will appear in its place. If you have a look at the source of that page, you’ll see the following:

<!-- Other stuff -->
<div id="page-content" class="content">

Both the title and the content of the post are encrypted with a 256-byte key that is constant and a 32-byte salt that is regenerated every time I generate the page. The cipher text is hex-formatted. I’m using crypto-js for encryption (on the server) and decryption (in the browser).

If you decide to use similar encryption to protect your private pages, keep the following things in mind:

  1. Keep your key secure. Make sure you don’t embed it in a page by mistake.
  2. Use a strong key. That means no birthdays, pet’s names or favorite authors.
  3. Use a well-written and audited cryptographic library. Any cryptographic algorithm is either perfectly implemented or completely broken, there’s no middle ground.
  4. Don’t link to the encrypted pages from any un-encrypted page. This is to ensure that visitors to your site don’t accidentally visit those pages. It also prevents crawlers from discovering those pages.