blockcrypt
blockcrypt copied to clipboard
Browser support
Hey Sun,
I came across this project after seeing your YouTube video on it and wanted to contribute :)
This PR enables support for using Blockcrypt in the browser while still maintaining a uniform experience while using Node.js. Here's a summary of the changes made:
- Configure TS, Node and Jest to support ECMAScript Modules.
- Replace Node built-in functions with browser-friendly alternatives (Uint8Array vs Buffer, Web Crypto vs Node.js core Crypto module).
- Refactor the code to more easily handle promises and iterations (since most browser crypto APIs are asynchronous).
Thank you for putting this project out there and for considering my contribution.
Sincerely, Chris
Hey Christoffer, very promising PR!
Thanks so much for contributing… adding browser support is a great idea.
I am currently backlogged with Superbacked launch… will review PR in dept ASAP.
One aspect of PR that might delay merge is the fact Superbacked relies on buffer inputs and outputs from Blockcrypt.
That said, uniform experience is likely worth adapting Superbacked code base.
Thanks again!
The code is now updated to keep the original API intact, meaning that Buffer
is used as inputs and outputs for encrypt
and decrypt
methods.
I've added encryptCompat
and decryptCompat
methods that will use Uint8Array
as inputs and outputs for maintaining compatibility with the browser.
Hopefully this approach can provide a good balance between both environments for now.
Thanks @christoffercarlsson… looking forward to reviewing PR.
Hey @sunknudsen,
It just occurred to me that the original API can be maintained for both environments by simply checking typeof window === 'object'
😄
If Blockcrypt is being used in the browser then Uint8Array
will be used for inputs and outputs, and if it's Node.js then Buffer
will be used. Subsequently, the encryptCompat
and decryptCompat
methods have been removed.
Hey @christoffercarlsson, starting to dive into PR.
Lots of work has gone into it, thanks for contributing.
Still exploring, but noticed that Message can no longer be of type Buffer
which is a breaking change with original API… is that intentional (relating to https://github.com/sunknudsen/blockcrypt/pull/2/commits/94badb18b562113fd81253e8992df090661e4bec)?
How does webcrypto compare to Node.js crypto APIs? Is webcrypto
simply a wrapper around crypto
on Node.js? My understanding is you recommend standardizing to webcrypto
to increase interoperability which is appealing, but I know very little about the browser side of things.
Overall, love the idea of supporting browsers and impressed by the amount of work put into this PR… some of which is outside of my zone of comfort (first time exploring webcrypto
APIs).
After spending about an hour reviewing PR, feels like codebase has become bulkier, harder to audit… likely because of webcrypto
having more complex APIs and lack of Buffer
(and, obviously, addition of interoperability, which is amazing).
I also noticed code has been (ingeniously) abstracted into more files and functions with a lot of inline sugar (use of inline await, reduce wizardry and wrapped promises (among other abstractions)… which yields less lines of code but perhaps makes code less readable (a “feature” I have come to appreciate especially for sensitive packages).
All that said, feedback comes from someone who may be a little old school… will let PR sink it and have a fresh look in a few days.
Thanks so much for contributing @christoffercarlsson.
Hey @sunknudsen,
Will try to answer as best I can to each of your comments:
Still exploring, but noticed that Message can no longer be of type
Buffer
which is a breaking change with original API… is that intentional (relating to 94badb1)?
The Buffer
type is compatible with Uint8Array
which means you can pass either a Buffer
or a Uint8Array
instance as a Message
, keeping the original API intact.
How does webcrypto compare to Node.js crypto APIs? Is
webcrypto
simply a wrapper aroundcrypto
on Node.js? My understanding is you recommend standardizing towebcrypto
to increase interoperability which is appealing, but I know very little about the browser side of things.
To my understanding, the built-in crypto
and the webcrypto
APIs are separated from each other but utilize the same OpenSSL functionality under the hood. The main difference between the APIs, that are relevant in this context, is how authentication tags for AES in Galois/Counter Mode are handled: In crypto
the authentication tag is separated from the ciphertext and is obtained by calling cipher.getAuthTag()
explicitly. In webcrypto
the authentication tag is automatically appended to the ciphertext.
After spending about an hour reviewing PR, feels like codebase has become bulkier, harder to audit… likely because of
webcrypto
having more complex APIs and lack ofBuffer
(and, obviously, addition of interoperability, which is amazing).I also noticed code has been (ingeniously) abstracted into more files and functions with a lot of inline sugar (use of inline await, reduce wizardry and wrapped promises (among other abstractions)… which yields less lines of code but perhaps makes code less readable (a “feature” I have come to appreciate especially for sensitive packages).
I absolutely agree with you - the code has become a bit bulkier and could really benefit from some refactoring towards readability, which is what I tried my best to do in the latest commit.
Thanks for taking the time to review this PR! :)