SRI hash generator
Give us the address of a script or a stylesheet and get the tag back with its integrity attribute, plus a check that the browser will accept it. You can also hash a file or pasted code, and that part stays on your device.
Or hash a file on your device
For a file that is not online yet, or one you would rather keep to yourself. The hash is computed by your browser: what you drop or paste here is not sent to us.
Choose a file, or drop one anywhere in this box.
A seal on code you don’t host
When your page loads a library from a CDN, you’re giving a stranger’s server the right to run code in front of your visitors. If that server gets broken into, or the project changes hands, the same address can start returning something else, like a card skimmer, a crypto miner or a redirect. Your page keeps working and you never notice. This has happened to real libraries used by hundreds of thousands of sites.
Subresource Integrity (SRI) is the browser feature that deals with this. You add a fingerprint of the file you reviewed to the tag, computed with a hash function such as SHA-384. The browser downloads the file, computes the fingerprint again, and runs the file only if the two match. Change a single byte and the fingerprint comes out different, so the file gets blocked.
<script src="https://cdn.example.com/lib@2.4.1/lib.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>What this page computes and checks
When you give an address, our server downloads the file once and sends an Origin header, the way a browser does for a tag with crossorigin. The hash is taken on the body after gzip or Brotli decoding, which is exactly what a browser hashes. You get the complete tag with SHA-384, and the SHA-256 and SHA-512 values as well.
A correct hash doesn’t guarantee the tag will work, so we read four more things from the response:
| Check | Why it matters |
|---|---|
Access-Control-Allow-Origin | For a file from another origin, the browser needs this permission before it’s allowed to compare bytes. Without it, a tag with integrity fails every time. Missing header: error. |
| Version in the address | /3.7.1/ or @5.3.3 returns the same file forever. @latest, @5, a branch name, a version only in ?ver=, or no version at all means the file can change, and the page breaks when it does. Warning. |
Cache-Control | A year-long or immutable lifetime suggests a frozen file. A lifetime under a day suggests the address is meant to change. |
Content-Type | Scripts have to come as JavaScript and stylesheets as text/css. Raw file viewers often send text/plain, which browsers refuse. |
A short list of addresses is refused outright: analytics and tag manager loaders, payment scripts, font stylesheets built per browser. Their owners rewrite them in place, so putting a hash on one is a way of scheduling an outage.
The second box hashes a file you drop, or code you paste, with the browser’s own crypto.subtle. Nothing is uploaded.
Using the tag without breaking your page
- Pin the version first. Change
library@latestto the exact release you tested, then generate the hash for that address. - Keep
crossorigin="anonymous". Without it the browser makes a request it isn’t allowed to inspect, and blocks the file. - Load the page and open the console. A mismatch shows up there as a failed integrity check, with the name of the file.
- Upgrade on purpose. A new version of the library needs a new address and a new hash. It’s a bit of work, and it’s also the point: nothing changes until you say so.
For files on your own domain, SRI doesn’t do much against an attacker who already controls your server, since they can edit the page and the hash together. It’s still useful when pages and assets are served from different systems, for example HTML from your server and files from your own CDN bucket.
Limits: one request from one place. A server may send other bytes to another browser or region, and we don’t check that the file is safe, only that it’s the same. An integrity attribute covers the file it’s on, not the scripts that file loads afterward.
Questions people ask
Which hash should I use: sha256, sha384 or sha512?
Browsers accept all three and none is known to be weak. SHA-384 is the convention. It’s what CDNs publish and what most documentation shows, so use it unless a policy tells you otherwise.
Why does my script stop loading after I add integrity?
There are three usual causes. The server doesn’t send Access-Control-Allow-Origin, or the tag lacks crossorigin="anonymous". The file changed since the hash was taken, because the address isn’t tied to a version. Or something between the server and the browser rewrites the file, such as a proxy that minifies scripts. The browser console tells you which.
Can I use SRI with Google Fonts, Google Analytics or Stripe?
No. Those addresses return content their owners update whenever they like, and the font stylesheet differs from one browser to another. A fixed hash would block them at the next change. Restrict them with a Content-Security-Policy instead.
Does the hash change if the server compresses the file?
No. The browser checks the file after decompression, so gzip, Brotli and zstd make no difference. Minifying or reformatting the file does change it.
Do images and fonts support the integrity attribute?
Not today. Browsers enforce it on <script> and on <link> for stylesheets, preloads and module preloads. On other elements it’s ignored.
How do I compute the same hash on the command line?
With OpenSSL: openssl dgst -sha384 -binary file.js | openssl base64 -A, then put sha384- in front of the output.