Starting to tackle the authorization & authentication scenarios described in #37 and #38 .
This PR introduces a library of crypto functions, along with tests, to support these scenarios. These functions aren't used anywhere besides tests yet. They currently live in the cevitxe package but may be moved to a cevitxe-crypto package.
These functions wrap the current best-in-class libraries as far as I've been able to determine - we're not rolling our own encryption.
New dependencies
I expected the javascript world to have a "standard" high-level library for encryption that works in Node.js as well as the browser. Turns out the landscape is still messy and confusing.
Node.js has a built-in crypto library, and a modern browser has an equivalent in the window.crypto.subtle library. I was able to find an isomorphic library that provides a common interface to both. But these are low-level libraries: the Web Crypto API explicitly warns developers against using it directly unless they know what they're doing:
I finally settled on the NaCl family of crypto APIs, all of which descend from a C library released in 2008 that was specifically designed not to expose footguns to developers.
scryptsy: A js implementation of scrypt, which we use to expand a password into a 32-byte key for symmetric encryption. It is in the same category of hashing algorithms as pbkdf2, bcrypt, sha256, etc.; and is designed to be expensive not just in CPU time but in memory usage.
fast-memoize: We memoize key derivation so we don't pay a penalty for encrypting/decrypting multiple items with a single password.
@stablelib/base64 and @stablelib/utf8: utilities for encoding/decoding base64 and utf-8
Starting to tackle the authorization & authentication scenarios described in #37 and #38 .
This PR introduces a library of crypto functions, along with tests, to support these scenarios. These functions aren't used anywhere besides tests yet. They currently live in the
cevitxe
package but may be moved to acevitxe-crypto
package.These functions wrap the current best-in-class libraries as far as I've been able to determine - we're not rolling our own encryption.
New dependencies
I expected the javascript world to have a "standard" high-level library for encryption that works in Node.js as well as the browser. Turns out the landscape is still messy and confusing.
Node.js has a built-in
crypto
library, and a modern browser has an equivalent in thewindow.crypto.subtle
library. I was able to find an isomorphic library that provides a common interface to both. But these are low-level libraries: the Web Crypto API explicitly warns developers against using it directly unless they know what they're doing:There's a widely used high-level library called crypto-js, but this predates the Web Crypto API and does not inspire confidence.
I finally settled on the NaCl family of crypto APIs, all of which descend from a C library released in 2008 that was specifically designed not to expose footguns to developers.
tweetnacl
: TweetNaCl.js is a small, fast, and audited javascript port with the same API as the original.scryptsy
: A js implementation ofscrypt
, which we use to expand a password into a 32-byte key for symmetric encryption. It is in the same category of hashing algorithms aspbkdf2
,bcrypt
,sha256
, etc.; and is designed to be expensive not just in CPU time but in memory usage.fast-memoize
: We memoize key derivation so we don't pay a penalty for encrypting/decrypting multiple items with a single password.@stablelib/base64
and@stablelib/utf8
: utilities for encoding/decoding base64 and utf-8