SHA-256 vs SHA-384 vs SHA-512 for SRI

Permalink to "SHA-256 vs SHA-384 vs SHA-512 for SRI"

Part of Understanding Cryptographic Hash Algorithms for SRI, this page is a decision guide: it helps you pick which of the three SRI-supported algorithms to standardize on, based on collision resistance, token length, compliance, and performance rather than on how to run the hashing commands.

Quick Reference

Permalink to "Quick Reference"
Property SHA-256 SHA-384 SHA-512
Algorithm identifier sha256 sha384 sha512
Digest size 256 bits 384 bits 512 bits
Collision resistance 128-bit 192-bit 256-bit
Base64 token length 44 chars 64 chars 88 chars
Underlying word size 32-bit 64-bit 64-bit
NIST SP 800-131A Approved Approved Approved
PCI DSS v4.0.1 Acceptable Recommended Acceptable
Relative performance (64-bit CPU) Baseline ~Same as SHA-512 Fast
Browser support All engines All engines All engines
When to choose Legacy or size-constrained Default for production High-assurance / payment pages

Standardize on SHA-384. Reach for SHA-512 only when a policy mandates the maximum digest, and drop to SHA-256 only when a legacy system cannot store the longer token.

How the three algorithms actually differ

Permalink to "How the three algorithms actually differ"

All three are members of the SHA-2 family defined in FIPS 180-4, and every current browser engine accepts all three in an integrity attribute. The security-relevant number is collision resistance, which is half the digest size: 128-bit for SHA-256, 192-bit for SHA-384, 256-bit for SHA-512. Even the weakest of these is astronomically beyond any collision attack demonstrated against a web asset, so for SRI the choice is dominated by two practical factors — token length and CPU cost — rather than by a real security gap.

The counter-intuitive detail is that SHA-384 is not slower than SHA-256. SHA-384 is a truncated variant of SHA-512, and both operate on 64-bit words, so on any modern 64-bit CPU they run at essentially the same speed — often faster than the 32-bit-word SHA-256. That is why the W3C recommends SHA-384 as the SRI baseline: you get 192-bit resistance and a shorter token than SHA-512 at no performance penalty. The step-by-step commands for producing these tokens live in How to Calculate SHA-256 vs SHA-384 for SRI; this page is about which one to commit to.


SRI Algorithm Trade-off Three bars of increasing height comparing SHA-256, SHA-384, and SHA-512 by base64 token length and collision-resistance bits, with SHA-384 marked as the recommended default. SHA-256 128-bit resistance 44-char token legacy / size-constrained SHA-384 192-bit resistance 64-char token 64-bit word speed default choice SHA-512 256-bit resistance 88-char token high-assurance taller box = more collision resistance and longer token

Canonical Comparison

Permalink to "Canonical Comparison"

To make an evidence-based choice, generate all three tokens for the exact bytes you will ship and compare them side by side. SHA-384 is the token you place in the tag; the other two are for the decision record. The mechanics of the digest commands themselves — binary mode, flag order, and the shasum equivalents — are covered in Generating SRI Hashes with OpenSSL and shasum.

# Produce all three SRI tokens for the served artifact
for algo in sha256 sha384 sha512; do
  printf '%s-' "$algo"
  openssl dgst -"$algo" -binary lib.min.js | openssl base64 -A
  echo
done

Expected output — note how the token grows with the digest size:

sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==

Every token has the same two-part shape: the algorithm name, a single hyphen, then the raw digest bytes in standard base64. Nothing about the encoding changes between algorithms — only the number of digest bytes does, and that is what drives the character count you see above. SHA-256 emits 32 bytes and lands on a 44-character token with one = of padding, SHA-384 emits 48 bytes and divides evenly into 64 characters with no padding at all, and SHA-512 emits 64 bytes and needs == to reach 88 characters.

Anatomy of an SRI Token The top row splits an integrity token into an algorithm prefix and a base64-encoded digest; below it, three proportional bars show that SHA-256 yields 44 characters with one padding character, SHA-384 yields 64 with no padding, and SHA-512 yields 88 with two padding characters. algorithm prefix base64-encoded digest sha384- oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC one hyphen separates the algorithm name from the digest Total token length by algorithm sha256- 44 base64 chars one pad char sha384- 64 base64 chars no padding sha512- 88 base64 chars two pad

The SHA-384 token is the one to deploy by default:

<script
  src="https://cdn.example.com/lib.min.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"></script>

Variant Examples

Permalink to "Variant Examples"

Multi-algorithm attribute for a rolling upgrade

Permalink to "Multi-algorithm attribute for a rolling upgrade"

If you are migrating an existing SHA-256 deployment to SHA-384, list both tokens. The browser evaluates only the strongest algorithm it supports and ignores the weaker one — this is a transition aid, not a requirement that both match:

<script
  src="https://cdn.example.com/lib.min.js"
  integrity="sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"></script>

Choosing per compliance regime

Permalink to "Choosing per compliance regime"

Match the algorithm to the strictest control you must satisfy. All three are NIST SP 800-131A approved, so the decision is about internal policy and payment-page scope:

General web assets ............... SHA-384 (W3C recommended default)
PCI DSS v4.0.1 payment pages ..... SHA-384 minimum; SHA-512 if policy mandates max digest
Legacy tooling / tight budgets ... SHA-256 (shortest token, still approved)
FIPS high-assurance systems ...... SHA-512 (256-bit resistance, longest token)

Reduced to a decision, only two questions ever change the answer: whether something downstream cannot store a 64-character token, and whether a written policy demands the largest available digest. If neither is true — which is the common case — SHA-384 wins by default.

Choosing an SRI Algorithm A two-question decision tree: if legacy tooling caps token length choose SHA-256, otherwise if policy mandates the maximum digest choose SHA-512, otherwise choose SHA-384 as the production default. Pick an SRI algorithm Legacy tooling caps token length? SHA-256 shortest token, approved yes no Policy mandates the maximum digest? SHA-512 256-bit resistance yes no SHA-384 — production default

Enforcing a single algorithm in the build

Permalink to "Enforcing a single algorithm in the build"

Pin your build tooling to one algorithm so tokens never drift between assets. For example, with the Webpack plugin:

// webpack.config.js — emit only sha384 tokens
import { SubresourceIntegrityPlugin } from 'webpack-subresource-integrity';

export default {
  output: { crossOriginLoading: 'anonymous' },
  plugins: [
    new SubresourceIntegrityPlugin({ hashFuncNames: ['sha384'] }),
  ],
};

Gotchas and Edge Cases

Permalink to "Gotchas and Edge Cases"
  • A longer hash is not meaningfully “more secure” for SRI. The jump from SHA-256’s 128-bit to SHA-512’s 256-bit collision resistance has no practical bearing on web-asset tampering, which relies on a preimage the attacker cannot compute at any of these sizes. Choose on token length and compliance, not on a false sense that bigger is safer.

  • SHA-224 and SHA-1 are not valid SRI algorithms. Only sha256, sha384, and sha512 are accepted. A token prefixed with anything else — including sha1 — is treated as an unrecognized digest and the browser reports that it could not find a valid digest, blocking the resource.

  • Always add crossorigin="anonymous" regardless of algorithm. The algorithm choice is irrelevant if the attribute is missing: without it the browser issues a no-CORS request, receives an opaque response it cannot read, and blocks the resource before any hash is compared. This omission is the most common SRI failure and is unrelated to which SHA variant you picked; How CORS and crossorigin Affect SRI covers the request modes and response headers involved.

  • Do not mix algorithms across a single asset’s history expecting AND semantics. Multiple space-separated tokens are OR-with-strongest-wins, never AND. Listing sha256-… and sha384-… does not force the browser to verify both.

  • Token length changes your CSP hash source too. If you also pin the script in a Content-Security-Policy script-src hash source, that hash must use the same algorithm and value; switching from SHA-256 to SHA-384 means updating both the integrity attribute and the CSP source.

Verification Steps

Permalink to "Verification Steps"

1. Confirm the deployed token uses your chosen algorithm

Permalink to "1. Confirm the deployed token uses your chosen algorithm"
grep -oE 'integrity="sha(256|384|512)-[^"]+"' dist/index.html | sort -u

Expected output when standardized on SHA-384 (values differ per asset):

integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"

Any sha256- or sha512- line here flags an asset that drifted from your standard. Turning that grep into a build-breaking assertion is the subject of Failing CI on SRI Hash Drift, which is the only reliable way to stop a stray algorithm from reaching production.

2. Re-derive the token from the served bytes

Permalink to "2. Re-derive the token from the served bytes"
curl -sL https://cdn.example.com/lib.min.js | openssl dgst -sha384 -binary | openssl base64 -A

The output must match the sha384- token in your HTML character-for-character.

3. Confirm clean validation in the browser

Permalink to "3. Confirm clean validation in the browser"

Load the page with DevTools open. A mismatched or unsupported algorithm produces this exact console error:

Failed to find a valid digest in the 'integrity' attribute for resource
'https://cdn.example.com/lib.min.js' with computed SHA-384 integrity
'sha384-…'. The resource has been blocked.

No message and a 200 OK in the Network tab confirms the algorithm and token are correct.

Frequently Asked Questions

Permalink to "Frequently Asked Questions"
Is SHA-512 more secure than SHA-384 for SRI?

SHA-512 offers 256-bit collision resistance versus 192-bit for SHA-384. Both are far beyond any feasible collision attack for web assets, so the practical security difference is negligible. SHA-512 mainly adds token length (88 vs 64 base64 characters). SHA-384 is a truncated SHA-512 computed at the same speed, which is why it is the recommended default.

Why is SHA-384 the default instead of SHA-256?

SHA-384 provides 192-bit collision resistance against SHA-256’s 128-bit, is the W3C-recommended algorithm for SRI, and satisfies PCI DSS v4.0.1 without the longest token length. On 64-bit CPUs it is also frequently faster than SHA-256 because the SHA-512 family uses 64-bit words.

Can I combine SHA-256 and SHA-384 in one integrity attribute?

Yes. Space-separate the tokens: integrity=“sha256-… sha384-…”. The browser evaluates only the strongest algorithm it supports from the list and ignores the rest. This is a migration aid, not a way to require both digests to match.

Does a longer hash meaningfully slow page load?

No. The difference between a SHA-256 and a SHA-512 token is roughly 44 bytes of uncompressed HTML per tag, which gzip collapses to almost nothing. Hash computation happens once per resource on already-downloaded bytes and is imperceptible next to network latency.


Permalink to "Related"

Related Articles

How to Calculate SHA-256 vs SHA-384 for SRI
Base64 Encoding Rules for SRI Hashes
Understanding Cryptographic Hash Algorithms Core SRI Fundamentals & Browse…