Hash Generator
Hash text or a file with MD5, SHA-1, SHA-2, SHA-3 or HMAC.
Related tools
- Password GeneratorGenerate strong random passwords in your browser with an entropy estimate.
- Encoder / DecoderEncode and decode Base64, URLs and HTML entities, and convert number bases.
- JWT DecoderDecode JWT header and claims, warn about the algorithm and header tricks that get tokens forged, sign new tokens, and verify HS, RS, PS and ES signatures in your browser.
About this tool
Hash Generator encodes the text you paste as UTF-8 and computes MD5, SHA-1, SHA-256, SHA-384 and SHA-512 at once, printed as lowercase hexadecimal; “Also show SHA-3” adds SHA3-224, SHA3-256, SHA3-384 and SHA3-512, computed by the page's own FIPS 202 implementation because Web Crypto has no SHA-3. Turn on “HMAC with a secret key” and it returns HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512 and, when SHA-3 is on, the four HMAC-SHA3 rows with the key you type (RFC 2104); there is no HMAC-MD5 row. It hashes a file you open as well as the text in the box, and it is not a password KDF: no salt, no iteration count, no bcrypt, scrypt, Argon2 or PBKDF2, so a digest produced here is not a way to store a password. MD5 and SHA-1 are kept for comparing checksums with tools that still print them, not for anything an attacker gets to influence.
The text and the HMAC key stay in the page - they are not uploaded to the XGM API and are not written into the URL, which keeps only the tool path, so a shared link carries no input. SHA-1, SHA-256, SHA-384 and SHA-512 come from crypto.subtle.digest, the keyed variants from crypto.subtle.importKey plus crypto.subtle.sign, and MD5 and the four SHA-3 lengths are implemented in the page's own JavaScript because Web Crypto provides neither. Copy and export build the file locally in the browser; nothing is stored between visits.
How to use it
- Open the Hash Generator tool.
- Paste or type the input you want to inspect.
- Read the result, which is computed in your browser; the input is not sent to XGM.
- Copy the output only after checking it looks correct.
- Use related XGM tools if you need a broader diagnostic view.
FAQ
Why is there no HMAC-MD5?
The keyed digests come from the browser's Web Crypto implementation, which offers HMAC over SHA-1, SHA-256, SHA-384 and SHA-512 and no MD5 at all. MD5 is computed by the page's own JavaScript and is left unkeyed: HMAC-MD5 has no modern use worth shipping, while HMAC-SHA3 does and is computed here (RFC 2104 over the SHA-3 sponge). That is why the MD5 row disappears as soon as you supply a key. If you need HMAC-MD5 for an old protocol, use a command-line tool such as openssl.
Can I store user passwords as SHA-256 digests?
No. SHA-256 is designed to be fast, and a single unsalted digest can be guessed at enormous rates on commodity GPUs, so a stolen table of digests is close to a table of passwords. Password storage needs a memory-hard or work-factor function with a per-user salt - Argon2id, scrypt, bcrypt or PBKDF2 (RFC 8018) - none of which this tool implements.
Are MD5 and SHA-1 useless now?
They are broken for anything adversarial: practical collision attacks exist for both, so they must not carry signatures, certificates or integrity guarantees. They are still fine as non-security checksums - comparing a download against a vendor page, deduplicating rows, matching a legacy ETag - where nobody is trying to craft a colliding input. Use SHA-256 or better everywhere else.
Why does my digest differ from sha256sum on the same text?
The input is hashed as the exact UTF-8 bytes in the box, with no trailing newline added. A shell echo appends a line feed, so echo "abc" | sha256sum hashes four bytes while this page hashes three; printf '%s' abc matches. Windows line endings are another common cause: CRLF and LF are different bytes and therefore different digests.
Does the HMAC key have to be a particular length?
Any length works. The key is taken as its raw UTF-8 bytes and handed to Web Crypto, which applies the RFC 2104 rule: a key longer than the hash block size is hashed first, a shorter one is zero-padded to the block. A key written in base64 or hex is used as that literal text, not decoded, so decode it yourself if the other side uses the raw bytes.