Browser engineering · · updated
Web Crypto vs cloud hashing: SHA-256 that never leaves RAM
The Web Cryptography API exposes SHA-256, SHA-384, SHA-512, and a CSPRNG in the page. Hashing with subtle.digest keeps the preimage in an ArrayBuffer. Generating a password with getRandomValues avoids Math.random. Cloud hash sites require the opposite: you give them the secret or the file. Run digests in the SHA-256 checksum tool and keys in the HMAC generator.
What does subtle.digest actually return?
crypto.subtle.digest(algorithm, data) returns a Promise<ArrayBuffer>. Algorithms are SHA-1, SHA-256, SHA-384, SHA-512. Output is raw bytes, not hex. You encode hex or base64 in JavaScript. The call is async because engines may farm the work out; it is still local. There is no network in the specification.
SRI hashes use the same digest with base64 and an algorithm prefix. File checksum pages print lowercase hex. Same primitive, different presentation. Do not send the file to either kind of site if you can run SubtleCrypto. The SHA-256 checksum tool is the hex form; SRI hash generator is the integrity-attribute form.
const buf = await file.arrayBuffer();
const digest = await crypto.subtle.digest("SHA-256", buf);
const hex = [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");Why must hashing be chunked for large files?
One arrayBuffer() of a multi-gigabyte Blob can OOM the tab. File.slice plus an incremental hasher keeps a 1–4 MB window. SubtleCrypto has no update() API; hash-wasm and similar WASM libraries do. MD5 still appears in legacy manifests — spark-md5 is incremental; it is not SHA-256 and it is not a password hash.
The file hash calculator is built for that loop. The long-form of the loop is the checksums article. Blob slicing is the File API primitive both sit on.
How is a password generated without Math.random?
Fill a Uint8Array with crypto.getRandomValues. Map bytes onto a charset. Naive modulo (byte % charset.length) biases unless the charset size divides 256. Rejection sampling discards bytes above the largest multiple of the charset size. That is what a serious in-browser generator does, including the secure password generator.
HMAC and password hashing are not the same. HMAC needs a key and a message (HMAC via Web Crypto). Password storage needs a KDF (Argon2, scrypt, PBKDF2), not SHA-256 of the password once.
What does a Network-tab audit show?
A local SHA-256 run should show no request whose body is your file. You may see the JS bundle and ads. A cloud hasher shows multipart/form-data or a JSON field with the string. Follow the Network-tab audit on the checksum page itself. If you see a POST of the file, leave.
Where Web Crypto cannot go
Non-extractable CryptoKey objects, PKCS#11, and HSMs are out of scope. AES-GCM and RSA-OAEP are in SubtleCrypto but are a different article. UUID v4 uses getRandomValues, not digest. The guarantee you do get is: digest and random stay in the process if you never fetch the preimage.
Which tool should you open?
Hex digest of a file or string: SHA-256 checksum. Several algorithms at once: file hash calculator. Script integrity: SRI generator. Keyed MAC: HMAC generator. Random secret: password generator.
Worked example: checksum a release tarball and an SRI script
Vendor publishes SHA-256 hex for a tarball. You download it to disk, open file hash calculator, match lowercase hex. If the file is huge, that tool chunks; the algorithm is still SHA-256 as in this article. Do not upload the tarball to a “hash website.” Confirm with Network tab.
Separately you pin a CDN widget. Save the exact JS bytes, run SRI generator, paste integrity and crossorigin on the script tag. Encoding differs (base64 vs hex) but SubtleCrypto digest is the same family. Recompute when the package version changes; a matching hash of the wrong file is worse than no SRI.
Passwords: open secure password generator, copy once, store in a manager. Do not hash the password with SHA-256 for storage. HMAC of API requests is HMAC in Web Crypto. File integrity without a key is this article and chunked checksums.
If digest throws, you are not in a secure context or the algorithm string is wrong (SHA256 vs SHA-256). Feature-detect. There is no honest fallback that POSTs the file to make the error go away.
Frequently asked questions
Is Web Crypto available in every browser tab?
subtle is available in secure contexts (HTTPS or localhost). HTTP origins may lack it. Check window.isSecureContext before promising a digest.
Why not hash a 2 GB file with one digest call?
subtle.digest wants the whole BufferSource. Large files need chunked File.slice hashing. Use the file hash calculator for multi-algorithm local checksums.
Can I use Math.random for passwords if I shuffle more?
No. Math.random is not a CSPRNG. The secure password generator uses getRandomValues and rejection sampling.
Is SHA-256 of a file the same as an SRI hash?
Same digest, different encoding. Checksums are usually lowercase hex. SRI is base64 with a sha256- prefix. See how SRI hashes are generated.