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 salva | Detectada |
|---|---|
| Editada e salva como atualização incremental | 100% |
| Composta através de um Form XObject | 89,4% |
Editada e depois reescrita pelo qpdf | 71,1% |
| Editada e depois redestilada pelo Ghostscript | 65,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
- O guia de campo das famílias de sinais — todo sinal estrutural que o motor reporta, com a causa benigna de cada um.
- Como saber se um PDF foi editado — a versão prática, com e sem ferramenta.
- O que significa uma string de producer — qual ferramenta escreveu o arquivo, e se ela criou o documento ou consumiu um que já existia.