# How to generate a Subresource Integrity (SRI) hash (/en/blog/generate-sri-hash)



Subresource Integrity (SRI) is the `integrity` attribute that makes the browser verify an external file's bytes against a hash you supply, and block the file if it does not match. To use it you need two things: the hash, and the right attribute on the tag.

Generate the hash with the [SRI generator](/tools/sri-hash): paste the file or URL and it returns the SHA-256, SHA-384, and SHA-512 values ready to paste. The value is the base64 digest of the raw file bytes. Prefix it with the algorithm and drop it on the tag, paired with `crossorigin` for a cross-origin file:

```html
<script
  src="https://cdn.example.com/script.js"
  integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
  crossorigin="anonymous"></script>
```

New to the mechanism itself? [Subresource Integrity (SRI) explained](/en/blog/subresource-integrity-sri) covers what it is and what it protects against. The rest of this post is the how-to and the traps that quietly break it.

## Pick the algorithm [#pick-the-algorithm]

SRI accepts `sha256`, `sha384`, and `sha512`. Prefer `sha384` or `sha512`. The digest is computed over the raw file bytes and base64-encoded, so the only thing that changes between algorithms is the strength and length of the value.

If you list more than one hash in the `integrity` value, the browser does not pick the first one. It uses the strongest algorithm present. A `sha256` next to a `sha384` means only the `sha384` hash is checked, so listing a weaker one alongside a stronger one never weakens the check. The [SRI generator](/tools/sri-hash) returns all three values, so you can paste whichever you want.

## Pair it with crossorigin [#pair-it-with-crossorigin]

A cross-origin `<script>` or `<link>` that carries `integrity` but no `crossorigin="anonymous"` always fails to load. This is the single most common SRI mistake.

Without `crossorigin`, the browser fetches the file in `no-cors` mode and gets an opaque response it cannot read, so it cannot verify the bytes against your hash and refuses to run the file. Adding the attribute switches the fetch to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) so the browser can read the response and check it.

```html
<link
  rel="stylesheet"
  href="https://cdn.example.com/styles.css"
  integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
  crossorigin="anonymous">
```

Same-origin files are already in a readable state, so they are checked without `crossorigin`. The attribute is the cross-origin requirement.

## Verify it works [#verify-it-works]

Load the page and watch for the file. A correct hash loads silently. A wrong hash, or a missing `crossorigin` on a cross-origin file, fails the load and logs an integrity error in the browser console.

To confirm a mismatch is caught on purpose, change one character in the `integrity` value and reload: the script should be blocked and the console should report that the resource failed its integrity check. Restore the correct value once you have seen the block.

## Keep hashes fresh when files change [#keep-hashes-fresh-when-files-change]

SRI does not auto-update. The hash is tied to the exact bytes of the file, so it must be regenerated every time the file content changes. That is the feature working as designed, a changed file with an old hash is treated as tampering and blocked.

This is why a "latest" or auto-minifying CDN URL breaks SRI: the bytes can change under you without warning, and the next deploy on their side blocks your page. Pin an immutable, versioned URL (a specific version path, not a moving tag) so the file you hashed is the file you keep getting.

The maintenance burden is also the reason teams track which third-party scripts they ship in the first place. CentralCSP builds a [script inventory](/platform/supply-chain) of every script running on your pages from CSP hash reports, so when a third-party file changes you see it instead of finding out from a blocked load.

## Do it with build tools [#do-it-with-build-tools]

Generating hashes by hand does not scale past a couple of files. Most bundlers can emit `integrity` attributes automatically as part of the build, so you can [automate it with Webpack or Vite](/en/blog/sri-webpack-vite):

* Webpack: [webpack-subresource-integrity](https://github.com/waysact/webpack-subresource-integrity) adds the `integrity` attribute to emitted `<script>` and `<link>` tags.
* Vite: a community plugin such as [@small-tech/vite-plugin-sri](https://github.com/small-tech/vite-plugin-sri) computes and injects the hashes at build time.

These keep the hash in sync with the file automatically, which removes the regenerate-on-change footgun for your own bundled assets.

## Not the same as a CSP hash [#not-the-same-as-a-csp-hash]

An SRI hash and a CSP hash look alike and are easy to confuse. They hash different things.

* SRI hashes an **external file** and goes in the `integrity` attribute on the tag.
* A CSP `'sha256-...'` source hashes **inline script content** and goes in the `script-src` directive of your Content Security Policy.

If you are allowlisting an inline `<script>` block, you want the CSP hash, not SRI. [How to generate a CSP hash (sha256)](/en/blog/csp-hash-sha256) covers that case.

## Where to require it [#where-to-require-it]

You add `integrity` per tag. To require SRI across a whole document instead of tag by tag, there is the `Integrity-Policy` header, which tells the browser to refuse any in-scope subresource that loads without integrity metadata.

```http
Integrity-Policy: blocked-destinations=(script)
```

Integrity-Policy recently became available across current Chrome, Firefox, and Safari. See the [Integrity-Policy](/en/docs/web-security/policies/integrity-policy) reference for the directives and the report it emits.

## Next steps [#next-steps]

Add `integrity` and `crossorigin` to your cross-origin scripts and stylesheets, pin their URLs, and wire your bundler to emit hashes for your own assets. If a scanner already pointed you here, see [if a scanner flagged your SRI](/en/blog/fix-sri-security-finding). To see what third-party code you are actually loading before you start hashing it, [start free](/register) and let CentralCSP inventory your client-side scripts.

## Sources [#sources]

* [MDN, Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)
* [W3C Subresource Integrity specification](https://www.w3.org/TR/SRI/)
* [srihash.org, SRI hash generator](https://www.srihash.org/)

## Related [#related]

* [Subresource Integrity (SRI) explained](/en/blog/subresource-integrity-sri)
* [How to generate a CSP hash (sha256)](/en/blog/csp-hash-sha256)
* [Subresource Integrity reference](/en/docs/web-security/other/subresource-integrity)
