O que uma assinatura realmente cobre

Três famílias de sinais sobre assinaturas digitais: quanto do arquivo a assinatura cobre, se o que foi assinado ainda é o que está ali, e o que o signatário permitiu mudar depois.

Um PDF assinado não é o mesmo que um PDF inalterado. Uma assinatura cobre uma faixa definida de bytes, e tudo que é anexado depois dessa faixa fica fora dela. Legitimamente, porque foi assim que o formato foi desenhado. Estas três famílias relatam a distância entre “este documento está assinado” e “este documento é o que foi assinado”.

Parte do guia de sinais: três das dezenove famílias que o motor reporta.

Sinais, não veredictos. Todo achado aqui é um fato estrutural sobre um arquivo. "Este documento foi modificado depois de gerado" é verdadeiro ou falso sobre os bytes; "este documento é fraudulento" é um julgamento sobre uma pessoa, e o Tamperlens não o faz. A API não retorna nenhum campo de veredicto booleano, por construção.

Uma assinatura de PDF protege duas faixas de bytes e deixa duas de fora: a lacuna onde ela mesma mora, e tudo que for anexado depois.
/ByteRange [ 0 a b c ] OS BYTES DO ARQUIVO → coberto coberto fora da cobertura a lacuna onde o valor da assinatura é escrito bytes anexados depois de assinar O QUE A FAMÍLIA CALCULA coveredEnd bytesAfterCoverage coversWholeFile ARITMÉTICA, NÃO CRIPTOGRAFIA dois inteiros comparados nenhum certificado é aberto, nenhuma cadeia de confiança é consultada

A faixa vermelha é normal e intencional em fluxos com mais de um signatário: o segundo assina anexando, e os bytes dele ficam fora do /ByteRange do primeiro. A Tamperlens reporta a lacuna; signature-permissions é quem pergunta se a mudança era permitida.

signature-coverage

info alta
O que detecta
Se o /ByteRange de cada assinatura de fato cobre o arquivo inteiro. /ByteRange é um array de pares deslocamento/comprimento que nomeia exatamente quais bytes uma assinatura protege. Normalmente tudo, exceto a lacuna onde fica o próprio valor da assinatura. A Tamperlens calcula o maior deslocamento coberto e o compara com o tamanho do arquivo. Qualquer coisa além dele foi anexada após a assinatura e não está protegida por aquela assinatura.
Este é o achado estrutural mais forte do motor, e é aritmética em vez de criptografia: dois inteiros, nenhum certificado necessário, nenhuma cadeia de confiança consultada. Ele vale independentemente de a matemática da assinatura validar, e é exatamente por isso que merece ser reportado separadamente da validação.
Evidência retornada
Por assinatura: número do objeto, /SubFilter, o array /ByteRange bruto, coveredEnd, bytesAfterCoverage, coversWholeFile e o tamanho total do arquivo. Mais uncoveredCount e a contagem de revisões do documento.
Causas legítimas
O mecanismo em si é uma parte normal e intencional do PDF: um segundo signatário, ou um salvamento incremental legítimo, como adicionar uma anotação permitida a um documento já assinado, produz bytes fora do intervalo da primeira assinatura. O PDF tem um conceito inteiro, as permissões DocMDP, para expressar quais mudanças posteriores um signatário permitiu. A Tamperlens reporta a lacuna de cobertura; ela não avalia se a mudança era permitida. Fluxos com múltiplas assinaturas, portanto, vão disparar este sinal legitimamente.
Duas coisas que esta família explicitamente não faz: verificar a criptografia da assinatura, e validar o certificado do signatário ou sua cadeia de confiança. São trabalhos separados, e um relatório de cobertura não substitui nenhum dos dois.
Lógica de severidade
Nenhum campo de assinatura: silenciosa. alta quando ao menos uma assinatura tem um /ByteRange interpretado que não alcança o fim do arquivo. info quando o documento está assinado e cada assinatura abrange o arquivo inteiro. Reportado deliberadamente, como um fato positivo que vale ter no relatório em vez do silêncio.

signature-integrity

alta baixa
O que detecta
Se os bytes que uma assinatura cobre ainda produzem o resumo com que aquela assinatura se comprometeu. Este é o par de signature-coverage, e os dois só fazem sentido juntos: a cobertura pergunta se algo foi acrescentado fora da faixa assinada, e este pergunta se algo mudou dentro dela. Um documento pode passar num e falhar no outro.
A diferença importa porque as explicações inocentes de cada um não são comparáveis. Bytes acrescentados depois de uma assinatura são completamente normais: um segundo signatário, uma anotação adicionada, um campo de formulário preenchido fazem exatamente isso. Um resumo que não confere não é: um PDF assinado corretamente não pode ter um. Algo dentro da região protegida foi alterado depois de protegido.
É aritmética sobre os próprios bytes do arquivo. O /ByteRange da assinatura nomeia as faixas que ela cobre; essas faixas são resumidas e comparadas com o atributo messageDigest dentro do bloco PKCS#7. Nenhuma requisição de rede é feita e nenhum relógio é lido, então o mesmo arquivo dá a mesma resposta para sempre.
Evidências retornadas
signatures, verified, mismatched e unreadable como contagens, depois findings com o status de cada assinatura, o algorithm do resumo e, quando diferem, os primeiros bytes de expectedDigest e actualDigest, para que a afirmação possa ser conferida em vez de aceita.
Causas legítimas
Para uma divergência, essencialmente nenhuma, e é por isso que este é o achado raro reportado como alta sozinho. Para um resultado ilegível há muitas, e ele é reportado como baixa justamente porque não é uma acusação: a assinatura simplesmente não está num formato que este motor leia.
O que não consegue ver
Isto não é validação de certificado, e um resumo conferido não é uma afirmação de que o documento é confiável. A Tamperlens não examina quem assinou, não percorre a cadeia de certificados até uma raiz confiável e não verifica se aquele certificado foi revogado. Uma assinatura matematicamente íntegra de um signatário completamente desconhecido se lê exatamente igual aqui a uma de um banco.
Só assinaturas PKCS#7 destacadas (adbe.pkcs7.detached, ETSI.CAdES.detached) são verificadas. adbe.pkcs7.sha1 é deliberadamente recusada em vez de aproximada: ela guarda seu resumo de outro jeito, e verificá-la da mesma forma reportaria uma divergência numa assinatura perfeitamente boa.
Lógica de severidade
alta quando os bytes cobertos não produzem o resumo comprometido. baixa quando uma assinatura está presente mas não pôde ser verificada: reportada em vez de omitida, porque o silêncio se leria igual a "verificada e em ordem". Um resumo conferido é reportado como info e não contribui em nada para a pontuação de risco.
As duas famílias fazem perguntas opostas sobre a mesma faixa de bytes, e um documento pode passar numa e falhar na outra.
signature-coverage Acrescentaram algo fora da faixa assinada? Explicações inocentes: um segundo signatário, uma anotação permitida, um campo de formulário preenchido. signature-integrity Mudou algo dentro da faixa assinada? Explicações inocentes: essencialmente nenhuma. Um PDF assinado corretamente não pode ter um resumo que não confere. As duas leem o mesmo /ByteRange, e por isso só fazem sentido juntas. Uma assinatura ilegível entra como baixa, não como silêncio: o silêncio se leria como “verificada e em ordem”.

Nenhuma requisição de rede é feita e nenhum relógio é lido em nenhuma das duas, então o mesmo arquivo dá a mesma resposta para sempre. Só assinaturas PKCS#7 destacadas são verificadas; adbe.pkcs7.sha1 é recusada em vez de aproximada.

signature-permissions

alta média baixa
O que detecta
Se o documento mudou de um jeito que a própria assinatura dele dizia que não podia. Esta é a terceira das famílias de assinatura e a que torna a primeira utilizável: a signature-coverage informa que bytes foram acrescentados depois da assinatura e então precisa listar as explicações inocentes, porque não consegue distingui-las. Uma assinatura de certificação já respondeu a essa pergunta no momento da assinatura.
Quando um documento é certificado, o signatário grava nele um nível de permissão: /DocMDP /P. 1 não permite alteração alguma; 2 permite preencher campos de formulário e acrescentar novas assinaturas; 3 permite também anotações. Esta família compara esse número com o que as revisões escritas depois de fato tocaram.
A maioria dos PDFs assinados não é certificada. Uma assinatura de aprovação comum atesta o documento como ele estava e não declara nada sobre o que pode vir depois, e isso também é reportado, porque "a assinatura cobre o arquivo inteiro" se lê como "verificada" quando significa apenas a extensão da assinatura, não a permissão de alguém. É a situação que o validador do ITI classifica como indeterminada.
Evidência retornada
docMDPPermission (e se foi docMDPPermissionDefaulted), permsTarget, appendedRevisions e um detalhamento touched que conta quantos fluxos de conteúdo de página, imagens, imagens alcançáveis por uma página, páginas, campos de formulário, outras anotações e objetos de assinatura as revisões posteriores escreveram, images e pageImages vêm separados, então 3 e 0 diz que chegaram imagens e que nenhuma delas caiu numa página: mais changedObjectSample, os números dos objetos por trás do achado, para que ele possa ser conferido no arquivo.
Causas benignas
Preencher um formulário regenera fluxos de aparência, que parecem fluxos de conteúdo e não são. Só objetos alcançados pelo /Contents de uma página contam aqui, e é isso que impede que um preenchimento permitido se leia como violação.
Uma assinatura visível carrega uma imagem. O bloco de assinatura renderizado, uma marca institucional, uma rubrica digitalizada . Tudo isso vive no fluxo de aparência do campo de assinatura, não na página, e acrescentar uma assinatura é exatamente o que o /P 2 permite. Só contam imagens que os recursos de uma página nomeiam. Medido sobre o corpus: 109 de 320 revisões que acrescentaram uma assinatura trazem uma imagem assim e nenhum conteúdo de página; antes da versão 1.24.0 do motor, todas elas seriam reportadas como violação.
Dados de validação de longo prazo. Acrescentar os certificados e respostas de revogação que permitem conferir uma assinatura anos depois cria uma revisão mesmo num documento certificado com /P 1. É rotina, é o que a política de Referência de Tempo da ICP-Brasil produz, e um documento cujo catálogo traz um armazenamento /DSS tem isso reportado como info, não como alteração.
O que não consegue ver
/P é um número num dicionário, e esta família não toma decisão de confiança alguma. Ela não verifica quem certificou o documento, se o certificado encadeia até uma raiz confiável, nem se a assinatura é válida. Essa última pergunta é da signature-integrity. Uma permissão declarada por um signatário desconhecido se lê exatamente igual a uma de um órgão público.
Ela não diz para que serviu a alteração. Reporta que um fluxo de conteúdo de página foi reescrito depois de uma certificação que não permitia isso, não o que a nova página diz.
Ela compara com a certificação e com mais nada. Num documento com várias assinaturas, uma alteração feita depois de um signatário anterior assinar mas antes de o documento ser certificado fazia parte do que foi certificado, e é invisível aqui. Essa é uma pergunta por assinatura, respondida separadamente pela signature-coverage e pela signature-integrity.
Um documento /P 3 pode ser alterado visivelmente sem que nenhuma permissão seja violada. /P 3 permite anotações, e uma anotação carrega conteúdo visível arbitrário no seu fluxo de aparência. A resposta correta pela norma e a resposta que um leitor quer não são a mesma coisa em /P 3, e nenhuma leitura do /DocMDP sozinha fecha essa lacuna.
Lógica de severidade
alta quando um fluxo de conteúdo de página, ou uma imagem que alguma página do documento nomeia, foi escrito depois da certificação (nenhum nível de permissão autoriza repintar a página), ou quando qualquer coisa foi alterada sob /P 1. alta também quando o catálogo aponta uma assinatura de certificação que não carrega certificação alguma, que é o que sobra quando se remove uma.
média quando uma anotação que não é campo de formulário aparece sob /P 2. baixa quando bytes foram acrescentados a um documento /P 1 mas tocaram apenas objetos de assinatura e de controle, sem um /DSS que os explique: um "olhe isto", não uma acusação. Todo o resto é info e não contribui em nada para a pontuação de risco: um documento não certificado, e uma assinatura que declara uma certificação que o catálogo nunca adotou. Esta segunda foi média por cerca de uma hora: medida contra 915 documentos reais, disparou 5 vezes e errou as 5, todas contratos públicos cujo produtor grava a transformação e omite a entrada do catálogo.
Uma assinatura de certificação já respondeu, na hora de assinar, o que podia vir depois. A maioria dos PDFs assinados não responde nada.
O QUE O SIGNATÁRIO GRAVOU EM /DOCMDP /P /P 1 nenhuma alteração permitida /P 2 preencher campos de formulário · acrescentar novas assinaturas /P 3 o acima, mais anotações sem certificação: a maioria dos PDFs assinados A assinatura atesta o documento como ele estava e não declara nada sobre o que pode vir depois. É a situação que o validador do ITI classifica como indeterminada.

O nível mais permissivo é o mais traiçoeiro de ler: /P 3 autoriza anotações, e uma anotação carrega conteúdo visível arbitrário no seu fluxo de aparência. Num documento /P 3, a resposta correta pela norma e a resposta que um leitor quer não são a mesma coisa, e nenhuma leitura do /DocMDP sozinha fecha essa lacuna.

A imagem de uma assinatura visível não fica na página, e é essa distinção que impede que assinar se leia como repintar.
NÃO CONTA campo de assinatura └ /AP · fluxo de aparência   └ imagem A rubrica digitalizada, o brasão, o bloco de assinatura renderizado: acrescentar uma assinatura é o que o /P 2 permite. CONTA COMO REPINTAR A PÁGINA página └ /Contents · /Resources   └ imagem Nenhum nível de permissão autoriza escrever um fluxo de conteúdo de página depois da certificação. Por isso a evidência separa images de pageImages: 3 e 0 diz que chegaram imagens e nenhuma caiu numa página.

O mesmo raciocínio vale para o preenchimento de formulário, que regenera fluxos de aparência parecidos com fluxos de conteúdo. Só objetos alcançados pelo /Contents de uma página contam, sem esse recorte, um preenchimento permitido se leria como violação.

Nenhuma das três famílias toma decisão de confiança: uma assinatura íntegra de um desconhecido se lê exatamente igual à de um banco.
O QUE ESTAS TRÊS RESPONDEM A faixa coberta chega ao fim do arquivo? Os bytes cobertos ainda produzem o resumo com que a assinatura se comprometeu? A alteração posterior respeitou o nível de permissão gravado na certificação? Todas são fatos sobre os bytes. O QUE NENHUMA DELAS RESPONDE Quem assinou. Se o certificado encadeia até uma raiz confiável. Se aquele certificado foi revogado. Todas são decisões de confiança. Para a metade que falta no Brasil, o validador do ITI é quem faz a validação criptográfica com a cadeia da ICP-Brasil.

O que o validador do ITI verifica, e o documento sem assinatura que ele não vê, está em uma página só sobre isso.

Quando a segunda parte assina, os bytes dela ficam além do /ByteRange da primeira, e é assim que um contrato normal vira o maior falso positivo já medido aqui.
DEPOIS DA PRIMEIRA ASSINATURA o /ByteRange da assinatura 1 alcança o fim do arquivo info DEPOIS DA SEGUNDA ASSINATURA o mesmo /ByteRange da assinatura 1 assinatura 2 alta Nada foi adulterado. Toda afirmação continua verdadeira sobre os bytes. Um contrato assinado por duas ou mais partes é o documento legítimo mais comum deste mercado, e hoje o motor o trata como sua saída de maior risco. Leia signature-integrity, que é a que de fato confere o digest, e signature-permissions.

Medido em 1.317 contratos de compras públicas federais do PNCP, com a separação entre assinados e não assinados e o mecanismo completo, em o que este motor erra, e como sabemos. Enquanto isso não é recalibrado, uma faixa high em PDF com múltiplas assinaturas é não informativa.

Veja o relatório no seu próprio arquivo

O verificador gratuito roda todas as famílias desta página e mostra a evidência completa, sem conta, sem nada armazenado. Para rodar no seu próprio fluxo, veja o guia rápido da API ou crie uma conta para uma chave com 50 documentos grátis por mês.

O Tamperlens reporta sinais de risco, não veredictos de autenticidade. Sinais podem ter causas legítimas; combine-os com sua própria lógica de decisão.

O resto do guia