Atualização incremental vs reescrita completa

Duas formas de salvar um PDF. Uma mantém todas as versões anteriores do documento dentro do arquivo; a outra não mantém nenhuma. Qual delas o seu editor escolheu decide o que alguém consegue provar depois.

Esta é a bifurcação mais consequente da forense de PDF, e quase ninguém fora do formato sabe que ela existe. A mesma edição visível — um total trocado, um nome coberto — deixa uma trilha de auditoria completa num modo de salvamento e quase nada no outro. Nenhum dos dois é suspeito. Os dois são o que software comum faz todo dia.

Atualização incremental: anexa a mudança, preserva o original

O PDF foi projetado para que um arquivo possa ser modificado sem ser reescrito. O editor deixa cada byte existente onde está, anexa os objetos que mudaram e escreve no fim uma nova tabela de referências cruzadas apontando para a anterior com /Prev. O resultado é um arquivo contendo dois documentos: o original, intacto, seguido do delta que substitui parte dele.

Quem abre vê a versão mais nova, porque a última tabela de referências vence. Um parser que anda para trás vê as duas. A versão anterior não está danificada, escondida nem criptografada — ela está simplesmente mais acima no arquivo.

O que aparece no fim de um arquivo atualizado incrementalmente

…documento original, byte a byte…
%%EOF                    ← o arquivo "terminou" aqui uma vez

6 0 obj                  ← a mudança anexada
<< /Length 84 >>
stream … endstream
endobj
xref                     ← uma segunda tabela de referências
trailer
<< /Prev 1024 … >>      ← apontando para a primeira
startxref
14394
%%EOF

É deste modo que uma assinatura digital depende. A assinatura cobre um intervalo de bytes; anexar depois desse intervalo deixa os bytes assinados intocados e verificáveis de forma independente — que é como um documento assinado pode depois ser contra-assinado, carimbado ou anotado sem invalidar a primeira assinatura.

Reescrita completa: uma passada, sem histórico

O outro modo escreve um arquivo novo do zero. A ferramenta interpreta o documento na memória e o serializa de volta: números de objeto novos, uma tabela de referências, nenhum /Prev, nada anexado. O que sai é um arquivo sem passado — não porque algo foi apagado, mas porque nada foi carregado adiante.

O Ghostscript faz isso. O qpdf --linearize também, assim como a maioria dos serviços de "comprimir PDF", todo driver de imprimir-para-PDF e o caminho de exportação da maior parte das ferramentas de design. É a forma normal de produzir um PDF a partir de algo que ainda não era um PDF.

Lado a lado

  Atualização incremental Reescrita completa
Versão anterior da página Continua no arquivo, recuperável Não existe mais
Tabelas de referências cruzadas Uma por salvamento, encadeadas por /Prev Exatamente uma
Números de objeto Numeração original preservada; objetos alterados reaproveitados Renumerados do zero
Assinatura digital existente Sobrevive, e continua cobrindo o que assinou Destruída — os bytes assinados não existem mais
Tamanho do arquivo após uma edição Cresce Costuma diminuir
Produtores típicos O Salvar do Acrobat, preenchimento de formulário, ferramentas de assinatura e carimbo Ghostscript, qpdf, imprimir-para-PDF, compressores, exportação de design
O que diz a quem analisa O que mudou, e o que estava escrito antes Que o arquivo foi escrito uma vez, por esta ferramenta

A diferença, medida

Construímos 1.006 falsificações a partir de documentos genuínos aplicando edições conhecidas, com toda fonte pontuando baixo antes, para que um falso positivo não pudesse ser confundido com um acerto, e rodamos o motor em todas. O modo de salvamento domina o resultado:

Como a falsificação foi salvaDetectada
Editada e salva como atualização incremental100%
Composta através de um Form XObject89,4%
Editada e depois reescrita pelo qpdf71,1%
Editada e depois redestilada pelo Ghostscript65,5%

Uma falsificação anexada é detectada todas as vezes. Passe a mesma falsificação por uma reescrita de arquivo inteiro e cerca de um terço da evidência some — não porque a reescrita escondeu algo de propósito, mas porque os rastros viviam numa estrutura que ela não carregou adiante. O que melhor sobrevive a uma reescrita é texto coberto, porque a forma que cobre e o texto embaixo dela são ambos conteúdo de página e são serializados juntos.

Medido no motor 1.23.0, contra as oito operações de edição em que pensamos. É um número de recall para formatos conhecidos de falsificação, não uma afirmação sobre falsificações que ninguém inventou ainda.

Nenhum dos dois modos é evidência de nada sozinho

Um PDF reescrito não é um PDF lavado, e um PDF com várias revisões não é um PDF adulterado. Este é o erro que a distinção mais produz, e ele acontece nas duas direções.

Todo PDF que começou a vida como outra coisa — um documento do Word, uma página web, uma planilha, uma digitalização — chega como reescrita completa. É simplesmente como ele foi feito. Tratar "uma revisão, objetos renumerados" como ocultação apontaria a maior parte dos documentos da internet.

E uma atualização incremental é o que a assinatura produz, o que o preenchimento de formulário produz, o que o carimbo de um sistema de folha de pagamento produz. Numa amostra de contratos públicos brasileiros publicados, a infraestrutura de assinatura do país produziu documentos de várias revisões por projeto. A contagem não significa nada; o que a revisão mudou é a pergunta, e a ferramenta de histórico de revisões responde exatamente isso.

Como saber qual você tem em mãos

Conte as tabelas de referências cruzadas. Uma significa que o arquivo foi escrito numa única passada; mais de uma significa que ele foi anexado, uma vez por tabela extra. Dá para ver isso sem ferramenta nenhuma procurando %%EOF dentro do PDF — um arquivo com três deles foi salvo três vezes.

Solte um PDF no histórico de revisões e ele desenha a cadeia: quantos salvamentos, quais objetos cada um substituiu, e se a mudança tocou o que a página exibe. Se a resposta for uma revisão só, a página diz isso com todas as letras, em vez de deixar você na dúvida entre não ter achado nada e não ter checado nada.

Relacionados