(Javascript) Cryptography is Hard
On the surface, something like login with Cognito doesn’t seem like it should require much. But when you look at something like aws-amplify-js, it’s surprisingly heavy. Even when you import only what you need, it can add around 150KB to your bundle. For smaller apps, that’s basically doubling your size just to support authentication.
I recently decided to rewrite a Cognito SRP helper library and remove the dependency weight by leaning entirely on native ECMAScript APIs instead of NodeJS libraries as shown below.
Once everything was refactored, the entire implementation came out to under 10KB minified for EVERYTHING. The size of my WHOLE library is 15x SMALLER than only using PART of aws-amplify-js. That's insane!
And that difference isn’t just theoretical... smaller bundles mean faster page loads and noticeably better Lambda cold start performance.
What caught me off guard wasn’t the SRP math itself. It was the data encoding details. Converting between binary, Base64, and hex is easy to get wrong. Hex encoding represents each byte as two characters. If you accidentally treat each hex digit as its own byte, your signatures break.
Below are some example conversions.
const uint8ArrayToHex = (uint8: Uint8Array): string =>
Array.from(uint8)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
export default uint8ArrayToHex;
function uint8ArrayFromBase64(value: string): Uint8Array {
const binaryString = atob(value);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
export default uint8ArrayFromBase64;
const uint8ArrayFromString = (str: string): Uint8Array => {
return new TextEncoder().encode(str);
};
export default fromString;
const hexFromBigInt = (value: bigint) : string => {
return value.toString(16);
};
While JavaScript has come a long way, regarding cryptography you still tend to notice more of what's missing and not what's there.
Would I recommend everyone dive into cryptography? Probably not. It’s easy to make subtle mistakes, and those mistakes matter. But working through it definitely changes how you think about data, performance, and abstractions. For me, that alone made it worth the effort.
If you’re curious, here’s the related discussion: https://github.com/simonmcallister0210/cognito-srp-helper/issues/63#issuecomment-3924253852