Trabajos de firma PFX incremental

La operación sign soporta un perfil incremental validado que preserva la revisión original exacta del PDF y cada firma criptográfica existente, a la vez que devuelve un artefacto firmado por separado

Selección de perfil

{"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}}

El perfil por defecto pfx-unsigned-document conserva el comportamiento original y acepta orígenes sin ningún campo de firma; crea un campo nuevo usando page, x1, y1, x2 e y2 y restaura el grafo de origen antes de publicar

pfx-incremental-document selecciona el perfil nuevo; incremental: true es un selector equivalente cuando se omite profile, y entra en conflicto con un profile explícitamente distinto

existingField: true rellena el campo de firma nombrado y vacío sin añadir otro campo; en caso contrario la operación crea un campo nuevo, y page y el rectángulo identifican su widget

El fieldName por defecto es Signature1 y acepta de 1 a 1024 bytes UTF-8; existingField exige un perfil incremental, un campo de firma coincidente y un valor V ausente o null

El bit 1 de Ff de solo lectura y los flags enteros malformados o fuera de rango se rechazan antes de la preparación; los diccionarios SV y Lock heredados se resuelven con nombres PDF semánticos únicos y un recorrido acotado de padres

Seed values y bloqueos de campo

digestMethod selecciona el digest CMS real SHA256, SHA384 o SHA512; SHA256 es el valor por defecto, mientras que cades: true selecciona ETSI.CAdES.detached e incluye el atributo signing-certificate-v2 que vincula el certificado de firma real

reason, location y contactName son cadenas JSON UTF-8 escritas como cadenas de texto Unicode PDF; las razones seed obligatorias comparan sus valores Unicode, incluido el valor especial de punto único que exige omitir la razón

Las restricciones SV obligatorias comprueban el handler real, el SubFilter CMS, la versión de firma soportada, el digest, la razón, el permiso de certificación, la attestation legal y el modo LockDocument; un timestamp obligatorio usa el transporte de la aplicación y el flujo de confianza explícito descritos en timestamps de firma de Windows, la evidencia de revocación firmada obligatoria usa firma autenticada de CRL y OCSP y las apariencias con nombre obligatorias usan presets reales de apariencia de firma generados

Las propiedades SVCert obligatorias validan el certificado hoja del PFX real y la cadena de issuers incluida, los bytes de certificado permitidos, los OIDs de política de certificado, los bits de key usage y los atributos DN de sujeto Unicode antes de firmar

credentialSourceURL aporta la procedencia de credenciales afirmada por la aplicación para una URL SVCert obligatoria; la biblioteca compara la URL declarada y el URLType soportado sin abrir ese endpoint ni autenticar una identidad de transporte

Los bloqueos de campo All, Include y Exclude se escriben como un diccionario indirecto SigFieldLock y una referencia FieldMDP coincidente vinculada al Catalog del documento; los nombres de campo usan cadenas de texto Unicode PDF y permanecen cifrados en documentos cifrados

Un valor P de Lock firmado limita las revisiones posteriores usando la política de campo firmada original, de forma independiente a cualquier permiso DocMDP; unas segundas firmas permitidas preservan la revisión anterior exacta y el CMS, mientras que un campo bloqueado o un cambio P1 se rechaza antes de publicar

La búsqueda de políticas decodifica los escapes de nombres PDF exactamente una vez, incluidos los nombres Parent heredados; los diccionarios con nombres semánticos duplicados y los padres inválidos o cíclicos se rechazan antes de publicar, mientras que los nombres escapados válidos retienen sus bytes de origen

contentsBytes vale 16384 por defecto y acepta de 1024 a 1048576; reason, location y contactName rellenan el nuevo diccionario de firma

Certificación y attestations legales

certificationPermission vale 0 por defecto para la firma de aprobación; 1, 2 o 3 crea una firma de certificación con el permiso DocMDP solicitado, vincula el DocMDP de Perms del Catalog al diccionario de firma indirecto real y retiene cualquier transformación FieldMDP independiente

La certificación debe ser la primera firma, y un documento solo puede contener una firma de certificación; los permisos de Catalog malformados, las referencias sin resolver y los valores DocMDP sin binding a un campo firmado original se rechazan

legalAttestation es una cadena Unicode opcional para la firma de certificación y se escribe en el Legal Attestation del Catalog; una lista LegalAttestation SV obligatoria debe contener el texto seleccionado, mientras que una lista obligatoria vacía exige omitirlo

Las firmas de certificación P2 y P3 existentes permiten firmas de aprobación posteriores cuando los bloqueos de campo y la política de revisión lo permiten; las firmas P1 y los campos bloqueados rechazan los cambios antes de la publicación binaria

Contrato del origen

El perfil incremental de trabajos acepta un origen original retenido, incluidos los PDF cifrados soportados, y un grafo de objetos cargado sin modificar; aporta password en la operación sign para un origen cifrado, por separado de pfxPassword

El password del origen autentica un snapshot bruto independiente, inicializa el contexto de cifrado original y reabre el candidato firmado; la revisión incremental resultante preserva el prefijo cifrado original, el diccionario de seguridad y el ID permanente del documento

El descifrado puede marcar objetos como dirty internamente o eliminar un diccionario de seguridad del grafo descifrado; la operación compara estos estados y las serializaciones acotadas de objetos contra una baseline de origen recién autenticada, mientras rechaza los cambios reales del grafo y todos los estados de objetos volcados

Con un password de usuario, un campo de firma existente exige permiso de relleno de formularios o de anotaciones, y un widget de firma nuevo exige permiso de anotaciones; un password de propietario autenticado autoriza cualquiera de las dos operaciones, sujeto a las políticas de firmas existentes

SaveLoadedDocumentToStream puede cambiar el estado de serialización; al firmar un grafo guardado o editado, recarga los bytes guardados en un handle nuevo y firma esa revisión

Mantén estable el almacenamiento del origen original durante la vida del handle; los trabajos de fichero deniegan el uso compartido de escritura mientras cargan y preparan su snapshot

El handle original retiene sus recuentos de campos, la identidad de los campos existentes, los valores de formulario, los bytes de origen y los ajustes previos de launch y decodificación; todo éxito de firma devuelve documentUpdated: false, y los fallos de firma dejan el handle disponible para consultas, guardado o una petición válida posterior

Los trabajos de fichero rechazan una ruta de salida igual o alias del fichero de entrada, incluidos los hard links; las APIs directas de stream rechazan los alias reconocibles de stream de origen y de fichero de origen, y los llamadores deben mantener además el almacenamiento de salida opaco de callbacks separado del almacenamiento de entrada

Preparación y validación

La operación copia los bytes brutos del origen a un snapshot temporal de creación exclusiva, abre un clon incremental independiente, añade el placeholder mediante SaveIncrementalUpdate acotado y rellena el CMS detached mediante el firmador nativo de streams PFX

El PFX permanece abierto con uso compartido de escritura denegado desde el preflight de tamaño hasta la firma; los ficheros temporales usan CREATE_NEW y solo se eliminan cuando la operación es dueña de su creación

El candidato firmado debe contener el prefijo de bytes exacto del origen y los recuentos esperados de formularios y campos de firma; la firma nueva debe verificar en su campo seleccionado, cada firma previamente rellenada debe seguir verificando, y el análisis de revisión de cada firma antigua debe aceptar las restricciones de DocMDP, FieldMDP, usage rights e identidad

Los campos antiguos sin rellenar se retienen sin contarse como preservedSignatures; las firmas existentes malformadas, inválidas o que violan la política provocan el rechazo antes de la publicación binaria

La verificación de firmas existentes comprueba la integridad CMS contra los bytes firmados y la política nativa de revisión; cuando se solicita timestamp para la firma nueva, su respuesta valida por separado la confianza TSA explícita y la evidencia de revocación configurada antes de publicar

Presupuestos y publicación

El techo efectivo de salida es min(outputBytes, memoryBytes / 8) e incluye el prefijo completo del origen, los objetos añadidos, el xref y la reserva de firma; effectiveOutputLimit informa del techo aplicado

El candidato sin firmar y la salida firmada quedan acotados por separado por ese techo, los bytes del PFX se acotan a memoryBytes / 8, y los presupuestos de decodificación de baseline de origen, clon y candidato se acotan por separado a memoryBytes / 8 con umbrales de spilling a fichero de 1 MiB como máximo

Estos son presupuestos de operación y de buffers, no una garantía estricta de RSS de proceso; la criptografía, los metadatos de objetos, el análisis de revisiones y el origen ya cargado del llamador pueden exigir memoria residente adicional

Las comprobaciones de cancelación y de tiempo transcurrido aplican a la copia del origen, la serialización y copia del delta, las lecturas del candidato, las lecturas de verificación de firmas, las lecturas del análisis de revisiones y la publicación por callback; los fallos nativos sticky de streams retienen su categoría de presupuesto o de cancelación en el borde del trabajo

La salida binaria se prepara en staging y se valida antes del primer callback de salida, y el tamaño del JSON de resultado se comprueba antes de la publicación binaria; la salida por callback en sí no es atómica, así que un callback binario o de resultado fallido puede dejar bytes que el llamador debe descartar

Los trabajos de fichero escriben en un candidato propio del mismo directorio, lo vuelcan, cierran los handles de origen y de salida y reemplazan atómicamente un destino distinto tras una validación con éxito; los fallos preservan un destino existente

El éxito devuelve mediaType: application/pdf, fieldName, profile, incremental, existingField, certificationPermission, revocationInfo, appearanceProfile, preservedSignatures, effectiveOutputLimit, outputBytes y documentUpdated: false

Aceptación por replay

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

El runner descubre RAD Studio mediante su RootDir del registro, acepta las sobrescrituras RADStudioRoot y PythonExecutable y usa la toolchain FPC configurada cuando se selecciona CheckFPC; FPCOnly hace replay solo de esos objetivos nativos, mientras que OpenSSLWin32Library y OpenSSLWin64Library seleccionan las bibliotecas runtime coincidentes para cada arquitectura

El runner sin GUI comprueba las APIs nativas de Win32 y Win64 y las DLL reales del C ABI usando callbacks parciales, campos vacíos existentes, firmas previas, seed values obligatorios, CAdES real SHA384 y SHA512, metadatos Unicode, segundas firmas permitidas y bloqueadas, propiedades reales de certificado PFX, transformaciones de bloqueo de campo AES-128 y AES-256, restricciones de permisos y credenciales de propietario, passwords incorrectos, grafos descifrados dirty, snapshots cifrados exactos del origen, recuperación del escritor cifrado in situ, fixtures reales de CMS DocMDP P1 y P2, presupuestos, cancelación, fallos de callback y reutilización del origen tras fallos

Las comprobaciones independientes de pypdf, MuPDF y OpenSSL prueban los prefijos previos y byte ranges exactos, el cifrado y los IDs permanentes intactos, el texto original buscable, los valores CMS antiguos y nuevos válidos, la excepción de cifrado de Contents de la firma y el rechazo del contenido firmado modificado; independent-proof.json registra los byte ranges y los resultados de las pruebas

Temas relacionados

Operaciones de documento, CopyLoadedSourceToStream, SaveIncrementalUpdate, EHPDFIncrementalOutputBudget