Password protection on a static site

Preamble

So I find myself needing another website, but not just another website for a family friends business or yet another rewrite of this website. No, I need a public website destined to only be visited by select people, guests if you will. This website is for a very special event (💒) and I want to make sure only the people who are supposed to see it can see it.

Ordinarily this task would not be difficult, just slap on some sort of authentication API and call it a day. However, I have continued to impose the constraint that the sites I make are generated/pre-rendered static sites, and that constraint makes it a little more difficult to password protect the site.

So what’s out there?

There’s a time and a place for using existing tools as is, but given the relative simplicity of how Staticrypt and Pagecrypt work, I opted to extend my build pipeline to add encryption capabilities. This way I can have more control over the encryption process and understand it better.

How it works

When a user tries to access the encrypted page, they will be prompted to enter a password. The password is used to derive an encryption key, which is then used to decrypt the page. If the password is correct, the encrypted content is decrypted and is displayed to the user. If the password is incorrect, an error message is shown.

The encryption transformer takes in a password and a static HTML page which is encrypted using AES-GCM with a key derived from the password using PBKDF2. The encrypted data, along with a random salt and iteration count, is then embedded into the new HTML file. The new HTML file also includes a password prompt and client-side JavaScript that handles the decryption process, error handling and accessibility features.

Security warning

This approach provides a reasonable level of security for protecting static content, given a sufficiently strong password is used. However, it is important to note that this method is vulnerable to offline attacks, where an attacker can download the encrypted page and attempt to brute-force the password. It’s also worth noting that I am not a security or cryptography expert, and this implementation is not intended to be used for protecting sensitive information. It is simply a way to add a layer of protection to static content that is not meant to be widely accessible.

Encryption in action

To see the encryption in action, try to see if you can access the encrypted page below.

Encrypted page

Password Hint

Weapon that needs catching.