PDFiumPas escribe cifrado ISO/TS 32003 mediante SaveAsEncrypted: fije Revision en erR7 y cada cadena y flujo quedan protegidos con AES-256 en modo GCM, el cifrado autenticado que PDF 2.0 obtuvo en 2023. Fije también EnableIntegrityProtection y el documento llevará además un token PDF MAC independiente, que ValidatePdfMac comprueba en el lado de la lectura
Son dos protecciones distintas que la gente confunde de forma habitual. GCM autentica cada valor cifrado. El MAC autentica el documento como un todo. Quiere ambas cosas, por razones diferentes
¿Qué añade GCM que CBC nunca ofreció?
Autenticación del texto cifrado. AES-256 en modo CBC, el esquema AESV3 de ISO 32000-2, mantiene el contenido confidencial y no dice nada sobre si llegó sin modificar. CBC es maleable de formas concretas y bien estudiadas: un atacante que pueda invertir bits en el texto cifrado produce cambios predecibles en el texto plano del siguiente bloque, y nada en el formato lo nota
GCM cierra eso. Cada valor cifrado lleva una etiqueta de autenticación de 16 bytes, serializada por completo como exige ISO/TS 32003, y el descifrado falla en lugar de devolver texto plano alterado cuando la etiqueta no coincide. En términos de PDF, una cadena o flujo manipulado en un documento AESV4 es un error irrecuperable en el momento de uso, no un valor extraño que se propaga por su aplicación. El diccionario Encrypt lo marca con /CFM /AESV4 y V 6 / R 7, junto con una entrada de extensión que declara /ExtensionLevel 32003 y /ExtensionRevision (:2023)
Tres revisiones, tres ecosistemas
TPdfEncryptionRevision ofrece erR5, erR6 y erR7, y la elección es más una decisión de compatibilidad que criptográfica. R5 es el esquema AES-256 original publicado como extensión de PDF 1.7, con un único hash de contraseña SHA-256, y se abre en prácticamente cualquier cosa de los últimos quince años. R6 es la derivación de clave endurecida normalizada en ISO 32000-2, mediante la construcción iterativa SHA-256/384/512 del algoritmo 2.B, y es lo que espera un flujo actual de PDF 2.0 o PDF/A-4. R7 es ISO/TS 32003, usando la misma derivación 2.B con AES-GCM como cifrador
El soporte de los lectores sigue exactamente ese orden, y el soporte de R7 todavía es escaso fuera de los visores mayoritarios actuales. Es la misma disyuntiva que gobierna cualquier función de PDF 2.0: la opción más nueva es la mejor ingeniería y la audiencia más estrecha. Decida según quién tiene que abrir el fichero, y si la respuesta es "un sistema de archivo documental que nadie ha actualizado desde 2019", la respuesta es R5 al margen de lo que prefiera la política de seguridad
uses
PDFium, FPdfEncrypt;
var
Pdf: TPdf;
Opts: TPdfEncryptOptions;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'quarterly-report.pdf';
Pdf.LoadDocument;
Opts := TPdfEncryptOptions.Default;
Opts.UserPassword := 'open-secret';
Opts.OwnerPassword := 'admin-secret';
Opts.EncryptMetadata := True;
Opts.Revision := erR7; // ISO/TS 32003 AESV4-GCM
Opts.EnableIntegrityProtection := True; // token PDF MAC independiente
if not Pdf.SaveAsEncrypted('quarterly-report.enc.pdf', Opts) then
raise Exception.Create('Encrypted save failed');
finally
Pdf.Free;
end;
end;
¿Por qué un MAC de documento sobre un cifrado ya autenticado?
Porque las etiquetas GCM protegen los valores, no la disposición de los valores. Cada cadena y flujo en un documento AESV4 está autenticado de forma individual, y sin embargo la tabla de referencias cruzadas, la numeración de objetos y el trailer son estructura, no contenido cifrado. Un atacante no puede falsificar un flujo, pero nada en el cifrador por sí solo le impide reorganizar a qué objetos apunta el documento, o empalmar objetos de una revisión anterior del mismo fichero
El token PDF MAC independiente aborda esa capa. PDFiumPas lo deriva de la clave de cifrado del fichero con un /KDFSalt dedicado de 32 bytes registrado en el diccionario Encrypt, así que poseer la contraseña es lo que permite a un lector confirmar el token. El resultado es una única respuesta a una única pregunta: ¿es este documento, en su conjunto, el documento que se escribió
var
Pdf: TPdf;
Mac: TPdfMacValidationResult;
begin
Pdf := TPdf.Create(nil);
try
Pdf.Password := 'open-secret';
Pdf.FileName := 'quarterly-report.enc.pdf';
Pdf.LoadDocument;
Mac := Pdf.ValidatePdfMac('open-secret');
case Mac.Status of
pmvsValid: ProcessDocument(Pdf);
pmvsNotPresent: ProcessWithWarning(Pdf); // sin token en este fichero
pmvsInvalid: Quarantine(Mac.MessageText); // manipulado o truncado
pmvsUnsupported: RouteForManualReview(Mac.MessageText);
end;
finally
Pdf.Free;
end;
end;
Los cuatro valores de estado necesitan cuatro respuestas distintas, y reducirlos a un booleano pierde la distinción que importa. pmvsNotPresent significa que el fichero simplemente no lleva token, lo cual describe a casi todos los PDF cifrados escritos antes de 2024 y no es evidencia de nada. pmvsInvalid significa que hay un token presente y no se verifica, un hallazgo genuino que debería detener el procesamiento. pmvsUnsupported significa que el token existe en una forma que esta compilación no implementa, una brecha de compatibilidad, no un ataque. Tratar "no presente" como "no válido" pondría en cuarentena todo su catálogo histórico el primer día
Lo que el cifrado sigue sin hacer
Los indicadores de permiso siguen siendo lo que siempre fueron: una petición al software conforme, no un control. Los bits /P de la Tabla 22 de ISO 32000-1 que prohíben imprimir o extraer los respetan los visores bien educados y los ignora todo lo demás, y cualquiera que posea la contraseña de usuario ya posee el contenido descifrado. El cifrado es la frontera; los permisos describen la intención dentro de ella
Dos detalles operativos merecen planificarse. Primero, el cifrado y la modificación posterior interactúan: añadir una actualización incremental a un documento cifrado tiene sus propias reglas, cubiertas en las actualizaciones incrementales en PDFs cifrados, y un token MAC es una afirmación a nivel de documento que un añadido descuidado invalidará. Segundo, la construcción GCM usa un contador de IV determinista, y PDFiumPas lanza una excepción en lugar de reutilizar un valor de contador si ese espacio llegara a agotarse alguna vez, porque la reutilización de nonce en GCM es catastrófica de una forma que un desbordamiento silencioso ocultaría
Cómo elegir entre las tres revisiones en la práctica
Anote quién abrirá el fichero, y luego elija. Para distribución interna donde cada lector es un visor actual bajo su control, R7 con protección de integridad es la opción más fuerte disponible y no hay ningún motivo para no usarla. Para documentos que salen de la organización, R6 es el valor por defecto defendible: está normalizado en ISO 32000-2 en lugar de en una especificación técnica encima de esa norma, y el soporte es amplio. Para archivos y consumidores heredados, R5 es la única opción que abre de forma fiable, y debería anotar el motivo en el mismo sitio donde registra el resto de su política de retención
Elija lo que elija, verifique la salida en lugar de confiar en que la llamada tuvo éxito. Vuelva a abrir el fichero cifrado, compruebe ValidatePdfMac, y confirme que la versión declarada es la esperada usando las comprobaciones de conformidad de versión en la conformidad exacta de versión de PDF. Una lista de comprobación de ingesta más amplia para documentos no confiables está en la auditoría de riesgos de seguridad en PDF
PDFiumPas es un componente para Delphi y Lazarus alrededor del motor PDFium con la pila de cifrado de PDF 2.0 implementada de forma nativa en Pascal, así que AES-256, GCM y el token MAC no necesitan ninguna DLL de criptografía externa. La API de cifrado está documentada en la página de PDFium para Delphi