Go Back to Pagination

Encrypted redirects and the Web Crypto API

Following up from last week's article about building your own url shortener, this week we'll tackle password-protected redirects. The simplest way that came to my mind to solve this problem is to generate the redirection page as usual but to save the redirection target as a password-encrypted string. Once the user provides the password via some means (e.g. a simple client-side form), they get redirected to the target URL. If the password is wrong a generic error message is displayed. The necessary cryptographic functions are provided by the Web Crypto Api. For this to work your shortener must be hosted in a secure context (HTTPS).

Now, I'm not a cryptographer (and it might show), so I got a lot of inspiration from restic, which is an audited backup solution. The idea is simple:

  1. Derive master-key k1 from a password p using a key-derivation function (PBKDF2) in CryptoKey-Format, which is used by Web Crypto.
  2. Derive a key k2 for use in AES-GCM from k1, using random 16-byte salt s. Use the Web Crypto CSPRNG.
  3. Get a random 12-Byte nonce iv using the Web Crypto CSPRNG.
  4. Get cyphertext ct by encrypting the URL url using AES-GCM together with iv and k2.
  5. Write a base64 encoded Byte Array consisting of [iv, salt, ct] into the source of the redirection page. This is called b64.
  6. Publish the redirection page.
  7. Once the user visits the redirection page, he gets prompted for p.
  8. Using p he can get k1.
  9. Using k1 and s (gotten from b64), he can get k2.
  10. Using k2 and iv (from b64), he can use AES-GCM to decrypt ct (from b64) to finally get url.
  11. Redirect him to url.

You can look at the actual implementation in the repository for krz-re. And a deployed example, redirecting to another article on this blog, here. The password is "password1234".

Of course, the user needs to share p out-of-band somehow, but that is left to the imagination of the host.

Base64-Conversions are not done using the native btoa or atob function, due to the Unicode Problem.

Conclusion

I really enjoy adding a couple of features to krz-re. It has proven useful not only for citations, as discussed last time but also as a way to securely share links with friends.