About SHA-384 Hash
SHA-384 takes an input of any length and produces a fixed 384-bit digest, written as 96 hexadecimal characters. The same input always gives the same digest, a one-character change gives a completely different one, and there is no way to run the function backwards to recover the input.
Internally it processes the message in 1024-bit blocks using 64-bit words, after padding the message and appending its bit length. That padding step is why hashing an empty string still produces a full-length digest rather than nothing.
SHA-384 is SHA-512 truncated to 384 bits, with different initial constants. Because it uses 64-bit words internally it is frequently *faster* than SHA-256 on 64-bit CPUs while producing a longer digest.
Truncation is not a weakness here - it is deliberate, and it also makes SHA-384 immune to the length-extension attack that plain SHA-256 and SHA-512 are vulnerable to. It is the hash paired with AES-256 in several TLS cipher suites.
SHA-384 shows up in two specific places: the TLS 1.2 and 1.3 cipher suites paired with AES-256, and Subresource Integrity hashes where a longer digest is wanted. It is otherwise uncommon, which means encountering one is usually a clue about which specification you are dealing with.
This page runs SHA-384 entirely in your browser through the Web Crypto API - the same implementation your browser uses for TLS. Nothing you paste is uploaded, logged, or leaves the tab, which matters when the thing you are hashing is a real token or customer record.
How to use the SHA-384 Hash
- Paste or type your input into the text box - any text, JSON, a token, or a whole file's contents.
- The 384-bit digest is computed as you type and shown as 96 lowercase hex characters.
- Use the copy button to take the digest, and compare it against the value you are checking against.
- Comparing two digests by eye is error-prone - paste both into the Text Diff tool if they are long, or compare the first and last eight characters at minimum.
Examples
-
Input
UUID Studio
SHA-384 Hash in code
The same operation this tool performs, in the languages you are most likely to need it.
const bytes = new TextEncoder().encode("hello world");
const digest = await crypto.subtle.digest("SHA-384", bytes);
const hex = [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
console.log(hex); // 96 hex characters
import { createHash } from "node:crypto";
const hex = createHash("sha384").update("hello world").digest("hex");
console.log(hex);
// Large files: stream instead of buffering the whole thing
import { createReadStream } from "node:fs";
import { pipeline } from "node:stream/promises";
const hash = createHash("sha384");
await pipeline(createReadStream("big.tar.gz"), hash);
console.log(hash.digest("hex"));
import hashlib
print(hashlib.sha384(b"hello world").hexdigest())
# Large files: read in chunks so you don't load it all into memory
h = hashlib.sha384()
with open("big.tar.gz", "rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
h.update(chunk)
print(h.hexdigest())
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
MessageDigest md = MessageDigest.getInstance("SHA-384");
byte[] digest = md.digest("hello world".getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) sb.append(String.format("%02x", b));
System.out.println(sb);
package main
import (
"crypto/sha512"
"encoding/hex"
"fmt"
)
func main() {
sum := sha512.Sum384([]byte("hello world"))
fmt.Println(hex.EncodeToString(sum[:]))
}
using System.Security.Cryptography;
using System.Text;
byte[] digest = SHA384.HashData(Encoding.UTF8.GetBytes("hello world"));
Console.WriteLine(Convert.ToHexString(digest).ToLowerInvariant());
# macOS / Linux
echo -n "hello world" | shasum -a 384 | cut -d" " -f1
# Note the -n: without it, echo appends a newline and you get a
# different digest than every other example on this page.
When you need this
- Generating a Subresource Integrity value where sha384 is the chosen prefix.
- Matching a digest produced by a TLS 1.3 cipher suite that uses SHA-384.
- Hashing on a 64-bit server where SHA-384 outperforms SHA-256 for large inputs.
- Meeting a specification that mandates a digest longer than 256 bits.
- Using a SHA-2 digest that is structurally immune to length extension.
Common problems and what causes them
- Expecting SHA-384 to be slower than SHA-256 because the digest is longer
- It is usually faster on 64-bit hardware. SHA-384 is SHA-512 internally, using 64-bit words and 1024-bit blocks, so for anything beyond very short inputs it processes more data per round than SHA-256 does. Digest length and speed are unrelated here.
- Truncating SHA-512 by hand instead of using SHA-384
- SHA-384 is not merely SHA-512 with the tail cut off - it uses different initial hash values. Truncating a SHA-512 digest yourself gives a different result and, unlike SHA-384, does not gain immunity to length extension.
- Your digest doesn't match the other system's, for the same input
- Almost always a trailing newline or an encoding difference. `echo "x"` appends \n but `echo -n "x"` does not, and a file saved with CRLF line endings hashes differently from the same file with LF. Hash the exact bytes, not the visually identical text.
- Hex vs Base64 vs raw bytes
- The same 384-bit digest can be printed as 96 hex characters, as Base64, or stored as 48 raw bytes. A mismatch is often just two systems formatting the same digest differently - decode both to bytes before concluding they differ.
- Uppercase vs lowercase hex
- Hex digests are case-insensitive as values but not as strings. `A3F1` and `a3f1` are the same digest and different strings, so a naive `==` comparison fails. Normalise case before comparing.
- Using SHA-384 to hash passwords
- A fast hash is the wrong tool for passwords - commodity hardware computes billions per second, so a leaked table is brute-forced quickly. Use bcrypt, scrypt or Argon2, which are deliberately slow and salted.
- Comparing digests with a non-constant-time comparison
- When you are checking a digest that acts as a secret or a signature, an early-exit string compare leaks how many leading characters matched. Use a constant-time comparison (`crypto.timingSafeEqual`, `hmac.compare_digest`, `MessageDigest.isEqual`).
FAQ
- What is the difference between SHA-384 and a truncated SHA-512?
- SHA-384 uses different initial constants, so its digest is not the first 384 bits of the SHA-512 digest of the same input. The truncation is also what makes it immune to length extension, which plain SHA-512 is not.
- Why would I choose SHA-384 over SHA-256?
- Three reasons: it is often faster on 64-bit CPUs despite the longer output, it is immune to length-extension attacks, and some specifications require it - notably the TLS cipher suites paired with AES-256.
- How long is a SHA-384 hash?
- Always 384 bits - 96 hexadecimal characters, or 48 bytes raw - no matter whether the input is one character or a gigabyte.
- Can a SHA-384 hash be decrypted or reversed?
- No. Hashing is not encryption; it discards information and has no key and no inverse. What people mean by "reversing" a hash is looking it up in a precomputed table of common inputs, which is why unsalted hashes of predictable values (short passwords, email addresses) are not private.
- Is SHA-384 safe to use in 2026?
- SHA-384 is SHA-512 truncated to 384 bits, with different initial constants. Because it uses 64-bit words internally it is frequently *faster* than SHA-256 on 64-bit CPUs while producing a longer digest.
- Why does the same text give a different hash elsewhere?
- Check for a trailing newline, CRLF vs LF line endings, a byte-order mark at the start of the file, or a different character encoding. All of those change the bytes without changing what you see on screen.
- Is this tool sending my input to a server?
- No. The digest is computed in your browser with the Web Crypto API. There is no upload, no request, and no logging - you can confirm it by opening your network tab, or by disconnecting from the network and using the tool offline.
- Should I use SHA-384 or HMAC-SHA-384?
- Use plain SHA-384 when you want an integrity check that anyone can recompute. Use HMAC-SHA-384 when the check has to prove the sender knew a shared secret - webhook signatures, API request signing, tamper-evident tokens. Never hand-roll that as hash(secret + message).