I'm trying to use crypto.subtle.digest()
as part of a checksum function for a file upload project I'm working on but for some reason I keep getting the following error:
upload-form.tsx:129 Uncaught TypeError: Cannot read properties of undefined (reading 'digest')
Which suggests that crypto.subtle
is undefined. I understand that crypto.subtle
is only available in a secure contexts (HTTPS), but I am trying to use it within http://localhost:3000
which I read was also considered a secure context. I have tried it in both Chrome & Firefox, and get the same undefined error in both.
I am using NextJS 14.1.0
and Node.js v20.11.0
I tested this on http://localhost:3000
on Chrome v121.0.6167.160
and Firefox ESR v115.3.0esr
I am using import * as crypto from "crypto"
within a Client Component (I have "use client";
at the top)
This is the checksum function I'm using which I got from this Youtube tutorial but only briefly shows it.
The comments are from ChatGPT who also came up with basically the same function.
//upload-form.tsx
"use client";
... //imports
import * as crypto from "crypto";
... //some code
const computeSHA256 = async (file: File) => {
// Convert file to an array buffer
const buffer = await file.arrayBuffer();
// Calculate SHA-256 hash
const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
// Convert hashBuffer to hexadecimal representation
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
return hashHex;
};
... //rest of file
Using crypto.webcrypto.subtle.digest()
, I get the error:
upload-form.tsx:133 Uncaught TypeError: Cannot read properties of undefined (reading 'subtle')
Which suggests that crypto.webcrypto
is undefined.
If I use window.crypto.subtle.digest()
instead, then the function runs perfectly fine, but I am wondering if that is the right way to go about it.
I used console.log(crypto)
to see what properties it had, and neither webcrypto
or subtle
was there.
Directly printing window.crypto
within Chrome's console shows that it does have subtle
Okay, so after looking into the github repo provided by the owner of the Youtube tutorial, I noticed that he never actually used import crypto from 'crypto'
at the top of his file. I wondered how he was able to use crypto without importing it, but I guess it turns out that without the import, javascript/react/nextjs (??) will default the crypto
variable to the Web Crypto API crypto
.
I had no clue that this was a thing.
If my understanding is correct, then, this is the same as just using window.crypto
, which was what I was using to get the function to work initially.
import * as crypto from 'crypto;
at the top of the filecrypto
variable will default to use window.crypto
, aka the Web Crypto APIcrypto.subtle.digest()
will work as intended.window.crypto.subtle.digest()
instead of the predefined crypto
variable.