VerifyKitv0.9.0
All comparisons
|9 min read|TrexoLab
nutrientpspdfkitcomparisonsignature verificationcertificate chainrevocationpades

VerifyKit vs Nutrient Web SDK for PDF Signature Verification

Nutrient (formerly PSPDFKit) is the other commercial SDK that validates PDF signatures client-side in JavaScript. Like Apryse, it is a full document platform where verification is one feature among many; VerifyKit is a verification engine that also renders.

Everything below is taken from Nutrient's own Web SDK validation guide, with the API names quoted so each row is checkable.

What Nutrient does that VerifyKit does not

Stated up front, because it is most of the product:

  • Signing, electronic and digital, with a signing UI.
  • Annotations, forms, redaction, editing, comparison, OCR.
  • Platform reach — Web, iOS, Android, Windows, server-side Document Engine, and a hosted API.

VerifyKit signs nothing and edits nothing. It verifies signatures and displays the document around them. If your requirement list includes any of the above, Nutrient is the broader tool and this comparison is only about the verification half.

What Nutrient's validation returns

The entry point is NutrientViewer.Instance#getSignaturesInfo(), resolving to a SignaturesInfo with a document-level status and documentModifiedSinceSignature, plus a signatures array ordered from least to most recent.

Each SignatureInfo exposes:

  • signatureValidationStatus — three values: valid ("no issues found"), warning ("concerns exist"), error ("the signature is invalid").
  • certificateChainValidationStatus and documentIntegrityStatus for deeper diagnostics.
  • Flags for whether the signing certificate is trusted, self-signed, or expired.
  • validFrom / validUntil.
  • timestampInfo, carrying the timestamp token issuer.

Trust roots come from NutrientViewer.Configuration#trustedCAsCallback, a promise returning DER ArrayBuffers or PEM strings, invoked when the instance loads.

That is a real validation surface — chain status and integrity status are separated, which is more than most libraries offer. Where it differs from VerifyKit is granularity and coverage, and there are four specific places.

The four differences that matter

1. B-LTA is not in Nutrient's PAdES enum

Nutrient reports PAdESSignatureLevel as one of NutrientViewer.PAdELevel.b_b, b_t or b_lt.

VerifyKit's padesLevel adds the fourth: B-LTA. That is the archival level — a signature carrying archive timestamps that keep it verifiable after the signing certificate, and the CA that issued it, have both expired. It is the level that matters for documents with a retention requirement measured in decades, and detecting it takes archive-timestamp chain analysis rather than a flag lookup.

If your documents are B-LTA, Nutrient's guide does not document a way to tell you so.

2. Revocation status is not a documented field

Nutrient's Web SDK validation guide names no revocation API, config flag, or status field. CRL and OCSP do not appear in it. Nutrient's product pages do state that the SDK "checks revocation status via OCSP and CRL" — so the capability is claimed; what is missing is a documented per-signature field where the developer reads the result.

VerifyKit surfaces revocationCheck as one of the eight checks, with a distinction few validators draw: it separates revoked before signing from revoked after signing, and flags revoked with no timestamp to prove when signing happened. A certificate revoked after a properly timestamped signature does not invalidate that signature — collapsing those cases into one boolean gets real documents wrong. The attempted flag then separates "we never checked" from "we checked and could not get a definitive answer," which is the difference between a configuration problem and a genuinely inconclusive certificate.

3. Three statuses versus eight checks

Nutrient gives you valid / warning / error plus two sub-statuses. VerifyKit reports eight checks independently:

integrityCheck          signatureCheck        certificateChainCheck   expiryCheck
timestampCheck          revocationCheck       algorithmCheck          ekuCheck

each with its own status, a detail string, and — on the algorithm check — an algorithmName so the UI can say "signed with SHA-1" whether or not that check passed.

The practical consequence: with three statuses, a signature that is cryptographically perfect but signed with a weak algorithm and a signature whose certificate chain does not resolve both surface as warning. Your UI cannot tell the user which, unless it re-derives it from the sub-statuses. With eight checks it is already separated.

4. Two licence components, and a silent failure between them

This is the one worth knowing before you build. Nutrient's guide states that signature validation requires both the Digital Signatures component and Form Viewing and Filling — because signatures live in form fields and their widget annotations.

Miss the second, and getSignaturesInfo() "resolves with an empty signatures array — even on a signed document," and no status bar renders. Not an error. Not a warning. A signed PDF that reports zero signatures.

Separately, the validation status UI ships disabled: showSignatureValidationStatus defaults to ShowSignatureValidationStatusMode.NEVER, so out of the box a signed document displays no validation state until you opt in with IF_SIGNED, HAS_WARNINGS or HAS_ERRORS.

VerifyKit has one licence covering the SDK, verification included, and the signature UI is what the default layout renders — there is no mode in which it silently reports a signed document as unsigned.

Where the verdict is drawn

Nutrient's validation UI is a status bar above the document, driven by showSignatureValidationStatus, plus per-signature information you can surface yourself. It ships disabled, as noted above.

VerifyKit puts the verdict where Acrobat puts it: inside the PDF canvas, on the signature field itself, in the widget's own rectangle at its scale and rotation — and the icon shown is the verdict that signature actually got from the eight checks, not the grey placeholder the signing tool baked into the file. Most web viewers render that placeholder forever, because they draw what is in the document.

The original bytes are never mutated: verification runs on them first, what reaches the renderer is display-only, and a download returns the untouched file. Password-protected documents are supported as well — not skipped, and not corrupted in the attempt.

Over that canvas, every signature field — signed and unsigned — is an individually addressable interactive overlay on the widget rectangle, tinted by that signature's status, with hover and highlight states and a click-through to the full detail: eight checks, certificate chain, timestamp, PAdES level.

The limit, stated plainly: other AcroForm fields render read-only. VerifyKit does not fill forms. Nutrient does, and that is a real reason to pick it.

Certificate detail

Nutrient's documented per-signature certificate information is the trusted / self-signed / expired flags plus validFrom and validUntil.

VerifyKit returns the parsed chain, with 21 fields on every certificate: subject, issuer, serial number, notBefore, notAfter, isExpired, isCA, subjectAltNames, SHA-256 and SHA-1 fingerprints, key algorithm, key size, signature algorithm, key usage, extended key usage, subject key ID, authority key ID, CRL distribution points, OCSP URLs, caIssuers URLs, certificate policies — and the raw DER bytes, so a UI can export any certificate or the whole chain as PEM, DER or .cer. The timestamping authority's own chain comes back the same way in timestamp.tsaCertificates.

Trust store

Nutrient starts from the roots you supply through trustedCAsCallback.

VerifyKit ships 134 embedded roots — 118 from the Adobe Approved Trust List and the 16-certificate Indian CCA hierarchy (CCA 2014/2015/2022 plus eMudhra, Capricorn, Protean, SafeScrypt, IDRBT, XtraTrust, PantaSign, NCode, IDSign, Verasys, C-DAC and CSC). A trustStore config adds yours in merge mode or replaces the built-ins in replace mode.

The CCA set is the practical one for Indian documents: DigiLocker, Income Tax, MCA and GST PDFs are signed under that hierarchy and are not covered by the AATL, so an AATL-only trust store reports every one of them as untrusted.

One place Nutrient is ahead here: certificateCheckTime lets you choose between 'signing_time' (their default, and the right one for LTV) and 'current_time'. VerifyKit evaluates expiry at signing time and reports the current-time consequence through the separate expiry and timestamp checks rather than as a switch — same information, less configurable.

At a glance

Nutrient Web SDKVerifyKit
Signs PDFsYesNo — verification only
Annotations / forms / redaction / OCRYesNo
PlatformsWeb, iOS, Android, Windows, server, hosted APIBrowser + Node.js
Per-signature statuses3 (valid/warning/error) + 2 sub-statuses8 independent checks
PAdES levelsb_b, b_t, b_ltB-B, B-T, B-LT, B-LTA
Revocation result fieldNot documented in the Web validation guiderevocationCheck, incl. revoked-after-signing
"Checked but inconclusive" vs "not checked"attempted flag
Status icon drawn inside the PDF canvasStatus bar above the documentYes, on the field, reflecting the computed verdict
Interactive per-signature field overlayEvery signature field, signed or unsigned
Fillable AcroForm fieldsYesNo — signature fields only
Certificate fields exposedtrusted / self-signed / expired, validFrom, validUntil21 fields per cert, full chain, raw DER
TSA certificate chainIssuer infotimestamp.tsaCertificates (full chain)
Built-in trust storeYou supply roots134 roots (118 AATL + 16 Indian CCA)
Certificate check time configurableYes (signing_time / current_time)Signing time, reported via separate checks
DocMDP certification levelmdpPermission
Deleted-signature detectionisDeleted + deletedAtRevision
Licence components neededDigital Signatures + Form Viewing and FillingOne
Validation UI defaultDisabled (NEVER)Rendered by the default layout
LicenceCommercial, quotedCommercial, quoted

Where a row says "not documented," it means Nutrient's Web SDK validation guide does not cover it — a question to put to them, not a proven absence.

How to choose

  • You need signing, forms, annotations or mobile SDKs. Nutrient. VerifyKit does none of them.
  • You already license Nutrient for editing and need basic valid/warning/error on signatures. Use what you have.
  • The verdict is the product — you are building a verification page, a compliance workflow, or an audit trail where "why did this fail" has to be answerable. Eight checks, full certificate chains and B-LTA detection are the reason VerifyKit exists.
  • Indian CCA-signed documents. The embedded CCA hierarchy decides it.

Try it on your own signed PDF in the live demo — the document is never uploaded. Then: Core Concepts, the Core API reference, and Revocation Checking. Licensing is by quote — get in touch.

References

Need PDF signature verification in production?

VerifyKit is a commercial SDK — try the live demo, then get in touch for a license.