Back to Blog
Security

Stop Using Vulnerable Hashing Approaches — Use WebCrypto

· Sanjeev

For a long time, hashing data in the browser meant one of two bad options: ship a third-party JavaScript implementation like crypto-js — tens of kilobytes of hand-rolled cryptography — or send the data to a server and hash it there, which defeats the point for anything sensitive. Both patterns still show up in production codebases today, and both are obsolete.

Every modern browser ships the WebCrypto API: audited, native, hardware-accelerated cryptographic primitives exposed through crypto.subtle. If you are still bundling a JS hashing library, you are paying bundle size and taking on implementation risk for something the platform gives you for free.

SubtleCrypto.digest in one snippet

Hashing a string with WebCrypto takes four lines: encode the text to bytes with TextEncoder, call crypto.subtle.digest("SHA-256", bytes), and convert the resulting ArrayBuffer to hex. The API is asynchronous by design, so large inputs never block the main thread — a real advantage over synchronous JS implementations that freeze the tab on multi-megabyte files.

The digest call supports SHA-1, SHA-256, SHA-384, and SHA-512. Notably absent: MD5. The standards body refused to include it, which tells you everything about its security status.

When MD5 and SHA-1 are still acceptable

MD5 and SHA-1 are cryptographically broken — practical collision attacks exist for both, so they must never protect passwords, signatures, or integrity against an attacker. But they persist legitimately as non-adversarial checksums: verifying a download completed, deduplicating files, matching a legacy system that already stores MD5s. The rule: if a malicious actor gains something by forging a collision, you need SHA-256 or better; if you are only detecting accidental corruption, the old algorithms are merely unfashionable.

Our Hash Generator implements exactly this split — SHA variants come from native WebCrypto, and MD5 is provided for legacy checksum work, all computed in your browser so the text you hash never leaves your machine.

Hashing is not encryption — and neither is Base64

Two confusions come up constantly. First, hashing is one-way: you cannot "decrypt" a SHA-256 hash, only test whether candidate input produces the same digest. Second, Base64 is neither hashing nor encryption — it is a reversible text encoding that anyone can decode instantly, as our Base64 Encoder/Decoder demonstrates. The same applies to JWTs: their payload is just Base64-encoded JSON, readable by anyone with a JWT decoder. The signature protects integrity, not confidentiality.

If you take one thing away: reach for the platform. WebCrypto for hashing and real cryptography, client-side execution for privacy, and third-party crypto libraries only when the platform genuinely lacks the primitive.