← blog
JavaScript Web Crypto API Zero dipendenze Audit trail

SHA-256 hash of a PDF with Web Crypto API, client-side

How to compute the SHA-256 hash of a PDF file directly in the browser with crypto.subtle.digest — for audit trails and document integrity verification, no external libraries.

The problem

In a document acknowledgement system, you need to prove the signed PDF is exactly the one shown to the user — without a dedicated backend for hash computation. The Web Crypto API allows this entirely client-side.

Hash computation from Blob

hash-pdf.js
async function calcolaHashPdf(pdfBlob) {
  const arrayBuffer = await pdfBlob.arrayBuffer();
  const hashBuffer  = await crypto.subtle.digest('SHA-256', arrayBuffer);
  const hashArray   = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

// Scarica blob da Firebase Storage e calcola hash prima di mostrare il documento
const pdfRef = storageRef(storage, item.pdfPath);
const url    = await getDownloadURL(pdfRef);
const res    = await fetch(url);
const blob   = await res.blob();
const hash   = await calcolaHashPdf(blob);

When to use it: document audit trails (acknowledgements, simple electronic signatures), verifying a downloaded file hasn't been altered, unique fingerprinting of user-uploaded files before saving.

The Firebase Storage CORS problem

The first attempt to download the PDF with fetch(downloadURL) often fails silently — no visible error in console, but the blob stays empty. The reason: Firebase Storage doesn't automatically configure CORS policies for fetch() requests from external origins, and the browser blocks the response before JavaScript can see it.

cors.json — configurazione CORS bucket
[
  {
    "origin": ["https://tuodominio.it"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
shell — applicazione con gsutil
# Richiede Google Cloud SDK installato
gsutil cors set cors.json gs://TUO-BUCKET.appspot.com

# Verifica configurazione applicata
gsutil cors get gs://TUO-BUCKET.appspot.com

Warning: CORS configuration is bucket-level and requires no code changes — but it must be applied once via gsutil; there's no equivalent panel in the Firebase Console.

Related article
Electronic signature with OTP on Firebase — audit trail, PDF hash and pdf-lib certificate

When to calculate a PDF's SHA-256 hash in the browser

This snippet shows how to calculate the SHA-256 hash of a PDF file directly in the browser using crypto.subtle.digest, with no external libraries, useful for audit trails and document integrity verification.

When to use it

When NOT to use it

Alternatives

Common mistakes

Frequently asked questions about SHA-256 hashing of PDF files

Calculating it in the browser avoids uploading the entire document to a server just to get its fingerprint, useful for sensitive documents or flows that need to stay client-side for privacy reasons.

Yes, this is the expected behavior of a cryptographic hash function like SHA-256: even a minimal content change produces a completely different hash, which makes it useful for detecting tampering.

No, crypto.subtle.digest is part of the native Web Crypto API in modern browsers: no external library is needed to calculate a file's SHA-256 hash.