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:

<title>9c8237cbe90e5a2254f9a20bf13bfa68265d67867e387699354bca6d31b13bcd</title>
<!-- Other stuff -->
<div id="page-content" class="content">
f8fa15c8ee53f1c1069e24577e7ba677bbdf14bb6f4e031820
f6b9c869b9cb6a7bbcfa25148d378871486f4cc7f5b6a3f107
ae19ed4c6a6386077b95be247bc6182e050414767e34eebe37
89bb2bc356e64c3f02c6897dc8729b71e2ae7e26ab
</div>

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.