Jobs de signature PFX incrémentale

L’opération sign prend en charge un profil incrémental validé qui préserve la révision PDF originale exacte et chaque signature cryptographique existante, tout en renvoyant un artefact signé séparément

Choisir un profil

{"schemaVersion":1,"type":"sign","profile":"pfx-incremental-document",
 "pfxFile":"C:/keys/signer.pfx","pfxPassword":"password",
 "fieldName":"ApprovalTwo","existingField":true,
 "budget":{"memoryBytes":268435456,"outputBytes":134217728,
           "resultBytes":16777216,"timeMilliseconds":60000,
           "objectCount":1000000,"pageCount":1024}}

Le profil pfx-unsigned-document par défaut conserve le comportement original et accepte des sources sans aucun champ de signature ; il crée un nouveau champ à partir de page, x1, y1, x2 et y2 et restaure le graphe source avant publication

pfx-incremental-document sélectionne le nouveau profil ; incremental: true est un sélecteur équivalent quand profile est omis, et entre en conflit avec un profil explicitement différent

existingField: true remplit le champ de signature nommé vide sans ajouter un autre champ ; sinon l’opération crée un nouveau champ, et page et rectangle identifient son widget

La valeur par défaut de fieldName est Signature1 et accepte de 1 à 1024 octets UTF-8 ; existingField exige un profil incrémental, un champ de signature correspondant et une valeur V absente ou null

Le bit 1 de Ff en lecture seule et les drapeaux entiers mal formés ou hors plage sont rejetés avant la préparation ; les dictionnaires SV et Lock hérités sont résolus avec des noms PDF sémantiques uniques et un parcours de parents borné

Seed values et field locks

digestMethod sélectionne le digest CMS réel SHA256, SHA384 ou SHA512 ; SHA256 est le défaut, tandis que cades: true sélectionne ETSI.CAdES.detached et inclut l’attribut signing-certificate-v2 qui lie le vrai certificat signant

reason, location et contactName sont des chaînes JSON UTF-8 écrites comme chaînes de texte Unicode PDF ; les reasons de seeds requises comparent leurs valeurs Unicode, y compris la valeur spéciale du point unique qui exige une reason omise

Les contraintes SV requises vérifient le handler réel, le SubFilter CMS, la version de signature prise en charge, le digest, la reason, la permission de certification, l’attestation légale et le mode LockDocument ; un timestamp requis utilise le transport applicatif et le workflow de confiance explicite décrits dans Windows signing timestamps, des preuves de révocation signées requises utilisent la signature authentifiée CRL et OCSP, et des apparences nommées requises utilisent les préréglages réels d’apparences de signature générées

Les propriétés SVCert requises valident avant signature le vrai certificat feuille du PFX et sa chaîne d’émetteurs incluse, les octets de certificats permis, les OIDs de politiques de certificats, les bits de key usage et les attributs DN de sujet Unicode

credentialSourceURL fournit une provenance d’identifiants affirmée par l’application pour une URL SVCert requise ; la bibliothèque compare l’URL déclarée et l’URLType pris en charge sans ouvrir ce endpoint ni authentifier une identité de transport

Les field locks All, Include et Exclude sont écrits comme dictionnaire SigFieldLock indirect et référence FieldMDP correspondante liée au Catalog du document ; les noms de champs utilisent des chaînes de texte Unicode PDF et restent chiffrés dans les documents chiffrés

Une valeur P de Lock signée limite les révisions ultérieures via la politique de champs signée originale, indépendamment de toute permission DocMDP ; une seconde signature permise préserve la révision et le CMS précédents exacts, tandis qu’un champ verrouillé ou un changement vers P1 est rejeté avant publication

La recherche de politiques décode les échappements de noms PDF exactement une fois, noms Parent hérités compris ; les dictionnaires avec noms sémantiques dupliqués et parents invalides ou cycliques sont rejetés avant publication, tandis que les noms échappés valides conservent leurs octets sources

contentsBytes vaut 16384 par défaut et accepte de 1024 à 1048576 ; reason, location et contactName remplissent le nouveau dictionnaire de signature

Certification et attestations légales

certificationPermission vaut 0 par défaut pour la signature d’approbation ; 1, 2 ou 3 crée une signature de certification avec la permission DocMDP demandée, lie Catalog Perms DocMDP au vrai dictionnaire de signature indirect et conserve toute transformation FieldMDP indépendante

La certification doit être la première signature et un document ne peut contenir qu’une seule signature de certification ; permissions Catalog mal formées, références non résolues et valeurs DocMDP sans liaison à un champ signé original sont rejetées

legalAttestation est une chaîne Unicode optionnelle pour la signature de certification et est écrite dans Catalog Legal Attestation ; une liste LegalAttestation de SV requise doit contenir le texte sélectionné, tandis qu’une liste requise vide exige l’omission

Les signatures de certification P2 et P3 existantes permettent une signature d’approbation ultérieure quand les field locks et la politique de révisions le permettent ; les signatures P1 et les champs verrouillés rejettent les changements avant publication binaire

Contrat de source

Le profil de job incrémental accepte une source originale retenue, y compris les PDF chiffrés pris en charge, et un graphe d’objets chargé non modifié ; fournissez password dans l’opération sign pour une source chiffrée, séparément de pfxPassword

Le mot de passe source authentifie un snapshot brut indépendant, initialise le contexte de chiffrement original et rouvre le candidat signé ; la révision incrémentale résultante préserve le préfixe chiffré original, le dictionnaire de sécurité et l’ID permanent du document

Le déchiffrement peut marquer des objets dirty en interne ou retirer un dictionnaire de sécurité du graphe déchiffré ; l’opération compare ces états et sérialisations d’objets bornées à une baseline source fraîchement authentifiée, tout en rejetant les vrais changements de graphe et tous les états d’objets flushés

Avec un mot de passe utilisateur, un champ de signature existant exige la permission de remplissage ou d’annotations, et un nouveau widget de signature exige la permission d’annotations ; un mot de passe propriétaire authentifié autorise l’une ou l’autre opération, sous réserve des politiques de signatures existantes

SaveLoadedDocumentToStream peut changer l’état de sérialisation ; quand vous signez un graphe sauvegardé ou édité, rechargez les octets sauvegardés dans un nouveau handle et signez cette révision

Gardez le stockage de la source originale stable pendant toute la durée de vie du handle ; les file jobs refusent le partage en écriture pendant le chargement et la préparation de leur snapshot

Le handle original conserve ses comptages de champs, l’identité des champs existants, les valeurs de formulaire, les octets sources et les réglages de launch et de décodage antérieurs ; chaque succès de signature renvoie documentUpdated: false, et les échecs de signature laissent le handle disponible pour une requête, une sauvegarde ou une demande valide ultérieure

Les file jobs rejettent un chemin de sortie égal ou alias du fichier d’entrée, hard links compris ; les API de flux directs rejettent les alias reconnaissables de flux et de fichiers sources, et les appelants doivent aussi garder le stockage de sortie opaque des callbacks distinct du stockage d’entrée

Préparation et validation

L’opération copie les octets sources bruts dans un snapshot temporaire créé exclusivement, ouvre un clone incrémental indépendant, ajoute le placeholder via un SaveIncrementalUpdate borné et remplit le CMS detached via le signateur natif de flux PFX

Le PFX reste ouvert avec le partage en écriture refusé, du preflight de taille jusqu’à la signature ; les fichiers temporaires utilisent CREATE_NEW et ne sont supprimés que lorsque l’opération est à l’origine de leur création

Le candidat signé doit contenir le préfixe d’octets source exact et les comptages attendus de champs de formulaire et de signature ; la nouvelle signature doit se vérifier dans son champ sélectionné, chaque signature antérieurement remplie doit encore se vérifier, et l’analyse de révisions de chaque ancienne signature doit accepter les contraintes DocMDP, FieldMDP, usage-rights et d’identité

Les anciens champs non remplis sont conservés sans être comptés comme preservedSignatures ; les signatures existantes mal formées, invalides ou violant une politique provoquent un rejet avant publication binaire

La vérification des signatures existantes contrôle l’intégrité CMS contre les octets signés et la politique native de révisions ; quand un timestamp est demandé pour la nouvelle signature, sa response valide séparément la confiance TSA explicite et les preuves de révocation configurées avant publication

Budgets et publication

Le plafond de sortie effectif est min(outputBytes, memoryBytes / 8) et inclut tout le préfixe source, les objets ajoutés, le xref et la réservation de signature ; effectiveOutputLimit rapporte le plafond appliqué

Le candidat non signé et la sortie signée sont bornés séparément par ce plafond, les octets du PFX sont plafonnés à memoryBytes / 8, et les budgets de décodage de baseline source, de clone et de candidat sont plafonnés séparément à memoryBytes / 8 avec des seuils de spill fichier d’au plus 1 Mio

Ce sont des budgets d’opérations et de buffers, pas une garantie stricte de RSS process ; le chiffrement, les métadonnées d’objets, l’analyse de révisions et la source déjà chargée par l’appelant peuvent exiger de la mémoire résidente supplémentaire

Les vérifications d’annulation et de temps écoulé s’appliquent à la copie source, à la sérialisation et copie du delta, aux lectures du candidat, aux lectures de vérification de signatures, aux lectures d’analyse de révisions et à la publication par callback ; les échecs natifs sticky conservent leur catégorie de budget ou d’annulation à la frontière du job

La sortie binaire est mise en scène et validée avant le premier callback de sortie, et la taille du JSON de résultat est vérifiée avant la publication binaire ; la sortie des callbacks n’est pas atomique, donc un callback binaire ou de résultat en échec peut laisser des octets que l’appelant doit jeter

Les file jobs écrivent dans un candidat possédé du même répertoire, le flush, ferment les handles source et sortie, et remplacent atomiquement une cible distincte après validation réussie ; les échecs préservent une destination existante

Le succès renvoie mediaType: application/pdf, fieldName, profile, incremental, existingField, certificationPermission, revocationInfo, appearanceProfile, preservedSignatures, effectiveOutputLimit, outputBytes et documentUpdated: false

Acceptation de replay

$env:HOTPDF_SUPPRESS_AUTO_LAUNCH = '1'
./Tests/CABI/Run-IncrementalSigningAcceptance.ps1 -BuildDLL -CheckFPC

Le runner découvre RAD Studio via son RootDir du registre, accepte les remplacements RADStudioRoot et PythonExecutable, et utilise la toolchain FPC configurée quand CheckFPC est sélectionné ; FPCOnly ne rejoue que ces cibles natives, tandis que OpenSSLWin32Library et OpenSSLWin64Library sélectionnent les bibliothèques runtime correspondantes pour chaque architecture

Le runner non-GUI vérifie les API natives Win32 et Win64 et les vraies DLL C ABI en utilisant callbacks partiels, champs vides existants, signatures antérieures, valeurs de seeds requises, CAdES réels SHA384 et SHA512, métadonnées Unicode, secondes signatures permises et verrouillées, propriétés réelles de certificats PFX, transformations de field locks AES-128 et AES-256, restrictions de permissions et identifiants propriétaire, mots de passe incorrects, graphes déchiffrés dirty, snapshots chiffrés exacts de sources, récupération du writer chiffré in-place, fixtures CMS réelles DocMDP P1 et P2, budgets, annulation, échecs de callbacks et réutilisation de sources après échecs

Des vérifications indépendantes pypdf, MuPDF et OpenSSL prouvent les préfixes antérieurs et byte ranges exacts, le chiffrement et les IDs permanents inchangés, le texte original cherchable, les valeurs CMS anciennes et nouvelles valides, l’exception de chiffrement du Contents de signature et le rejet de contenu signé modifié ; independent-proof.json enregistre les byte ranges et résultats de preuves

Sujets liés

Opérations documentaires, CopyLoadedSourceToStream, SaveIncrementalUpdate, EHPDFIncrementalOutputBudget