Skip to content
JustDevTools
  • JSON formatter and validator
    Format, minify and validate JSON, with the exact line and column of any syntax error.
  • JWT decoder
    Read a JWT's header and payload, with issued-at and expiry times shown as real dates.
  • Base64 encoder and decoder
    Encode and decode Base64 and Base64URL, with full Unicode support.
  • JSON to TypeScript, Zod and Java
    Paste a JSON response and get TypeScript interfaces, a Zod schema or Java classes with Jackson annotations.
  • YAML to JSON converter
    Convert YAML to JSON and JSON to YAML, with the exact line of any syntax error. Handles multi-document files.
  • Regex tester
    Test JavaScript regular expressions with live match highlighting, capture groups and replace preview.
  • URL encoder and decoder
    Percent-encode and decode URLs and query values, and break a URL into its parts and parameters.
  • Unix timestamp converter
    Convert Unix timestamps in seconds or milliseconds to dates, and dates back to timestamps.
  • Cron expression explainer
    See what a cron expression means in plain English, what each field does and the next times it will run.
  • JSON to CSV converter
    Turn a JSON array into CSV for Excel or Google Sheets, or a CSV file into JSON. Nested objects become columns.
  • UUID generator and inspector
    Generate UUID v4 and time-ordered v7 in bulk, or paste a UUID to see its version and timestamp.
  • Text diff checker
    Compare two texts line by line and see exactly what was added, removed or changed.
  • Hash and HMAC generator
    SHA-256, SHA-1, SHA-384 and SHA-512 hashes and HMAC signatures of text, in hex or Base64.
  • Markdown previewer
    Write Markdown on the left and see it rendered live on the right, with GitHub-style tables and task lists.

Hash and HMAC generator

SHA-256, SHA-1, SHA-384 and SHA-512 hashes and HMAC signatures of text, in hex or Base64.

Runs locally. Nothing you paste leaves this tab.

Hashes

  • SHA-256
    …
  • SHA-1
    …
  • SHA-384
    …
  • SHA-512
    …

Hashes and HMACs

A hash such as SHA-256 turns any input into a fixed-length fingerprint. The same input always gives the same output, and a one-character change gives a completely different one. Use it to check that a file or payload hasn’t changed.

An HMAC mixes a secret key into the hash. Only someone with the key can produce the right value, so it proves who sent a message as well as that it wasn’t changed. Stripe, GitHub, Shopify and Slack all sign webhooks this way.

Debugging a webhook signature

  1. Turn on HMAC and paste the signing secret from the provider’s dashboard.
  2. Paste the raw request body, exactly as received. Parsing the JSON and serialising it again changes spacing and key order, and the signature will no longer match. This is the most common cause of failed verification.
  3. Pick the encoding the provider uses (GitHub and Stripe use hex, Shopify uses Base64).
  4. Paste the signature from the header into the compare box. A sha256= prefix is ignored.

Some providers sign more than the body. Stripe signs {timestamp}.{body}, and Slack signs v0:{timestamp}:{body}. Build that exact string before hashing.

Which algorithm?

Use SHA-256 unless something else requires otherwise. SHA-1 is broken for collision resistance and should only be used to talk to legacy systems (HMAC-SHA1 itself is still considered safe). MD5 isn’t offered because browsers don’t include it, and it shouldn’t be used for anything security-related.

Don’t hash passwords with SHA-256. It is designed to be fast, which makes brute force cheap. Use Argon2id, scrypt or bcrypt.

In code

// Node.js
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
createHash("sha256").update(body).digest("hex");
const sig = createHmac("sha256", secret).update(rawBody).digest("hex");
timingSafeEqual(Buffer.from(sig), Buffer.from(received)); // compare in constant time

// Java
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(UTF_8), "HmacSHA256"));
HexFormat.of().formatHex(mac.doFinal(body.getBytes(UTF_8)));

// Python
import hmac, hashlib
hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()

# Shell
printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET"

Note the printf '%s': echo adds a trailing newline, which changes the hash.