Uma assinatura digital prova duas coisas ao mesmo tempo: que uma mensagem veio mesmo de quem afirma tê-la enviado e que não foi alterada pelo caminho. É o equivalente eletrónico de uma assinatura manuscrita, mas com garantias matemáticas que uma rubrica em papel nunca poderá oferecer. Por detrás dela estão duas ferramentas que já aparecem noutros artigos desta secção: uma função de hash e um par de chaves assimétricas. Este texto explica como se combinam, passo a passo, e por que motivo uma colisão de hash, como a do SHAttered, ameaça diretamente a sua segurança.
As duas peças: hashing e chaves assimétricas
Para perceber uma assinatura digital, convém ter presentes os dois blocos que a compõem.
O primeiro é a função de hash criptográfica. Como se descreve no artigo sobre funções de hash, ela reduz uma mensagem de qualquer tamanho a um resumo de comprimento fixo, que funciona como impressão digital dos dados. O resumo é determinístico e sensível à mínima alteração, graças ao efeito de avalanche.
O segundo é a criptografia assimétrica, também chamada de chave pública. Em vez de uma única chave secreta partilhada, cada pessoa tem um par de chaves matematicamente ligadas: uma chave privada, que se mantém em segredo, e uma chave pública, que se pode distribuir livremente. O que uma das chaves faz, só a outra do par desfaz. Esta relação é o que permite a uma pessoa provar identidade sem revelar o seu segredo.
A combinação destas duas peças é mais eficiente do que assinar a mensagem inteira diretamente. Em vez de aplicar a operação de chave, que é relativamente lenta, sobre todo o documento, aplica-se apenas sobre o resumo, que é curto e de tamanho fixo. Assina-se a impressão digital, não o documento completo.
Assinar: o processo passo a passo
Do lado de quem assina, o procedimento tem três passos.
Primeiro, calcula-se o resumo da mensagem com uma função de hash criptográfica. O documento, por maior que seja, fica reduzido a uma cadeia curta de bytes que o identifica de forma fiável.
Segundo, aplica-se a chave privada sobre esse resumo. O resultado desta operação é a assinatura. Repare-se que só o detentor da chave privada consegue produzir uma assinatura válida, porque só ele possui essa chave. Este é o passo que liga, de forma inquebrável, a identidade do signatário àquele resumo concreto.
Terceiro, a assinatura é enviada ou guardada junto da mensagem. A mensagem em si não fica cifrada nem escondida; continua legível por todos. A assinatura é um acréscimo que permite a qualquer pessoa verificar a sua autenticidade e integridade.
Verificar: confirmar autoria e integridade
Do lado de quem recebe, a verificação espelha o processo de assinatura e usa a chave pública.
O verificador começa por calcular, ele próprio, o resumo da mensagem recebida, com a mesma função de hash. Em seguida, aplica a chave pública do alegado signatário sobre a assinatura, o que devolve o resumo que estava lá guardado no momento de assinar. Por fim, compara os dois resumos: o que calculou a partir da mensagem e o que obteve da assinatura.
Se os dois coincidem, ficam provadas duas coisas em simultâneo. A mensagem não foi alterada, porque qualquer alteração, por mínima que fosse, teria mudado o resumo calculado e a comparação falharia. E a mensagem veio mesmo do dono daquela chave privada, porque só a chave pública correspondente consegue recuperar o resumo de uma assinatura feita com a chave privada certa.
Se os resumos não coincidem, a verificação falha, e isso pode significar que a mensagem foi adulterada, que a assinatura foi forjada ou que a chave pública usada não corresponde a quem assinou de facto. Em qualquer dos casos, a assinatura não merece confiança.
Por que uma colisão de hash ameaça as assinaturas
Aqui está o ponto em que toda a secção se liga. Como a assinatura cobre o resumo, e não o documento inteiro, a segurança de todo o esquema depende de o resumo ser único para aquele documento. Se a função de hash for resistente a colisões, isso está garantido. Se não for, abre-se uma brecha grave.
Imagine que um atacante consegue preparar dois documentos diferentes com o mesmo resumo, um inofensivo e um malicioso. Apresenta o documento inofensivo para ser assinado. A assinatura, feita sobre o resumo desse documento, é igualmente válida sobre o documento malicioso, porque ambos partilham exatamente o mesmo resumo. O atacante troca depois um pelo outro, e a assinatura continua a verificar na perfeição. A vítima assinou uma coisa e fica vinculada a outra.
Foi precisamente este cenário que a nossa investigação tornou concreto. O SHAttered produziu dois ficheiros PDF diferentes com o mesmo hash SHA-1, e o artigo sobre a colisão de SHA-1 descreve o caso em detalhe. A partir do momento em que uma colisão é prática, qualquer assinatura assente nessa função de hash deixa de ser de confiança. Foi esta ameaça, e não uma preocupação meramente teórica, que acelerou o abandono do SHA-1 em assinaturas e certificados, a favor do SHA-256.
Onde as assinaturas digitais aparecem
O mecanismo é o mesmo em muitos contextos, ainda que com nomes e formatos diferentes.
Certificados e TLS
Quando um navegador estabelece uma ligação segura, confia num certificado que associa um nome de domínio a uma chave pública. Esse certificado é assinado por uma autoridade de certificação, e a assinatura é verificada com a chave pública dessa autoridade. É uma cadeia de assinaturas digitais que sustenta toda a confiança no cadeado do navegador. Se um atacante conseguisse forjar uma assinatura sobre um certificado em colisão, poderia fazer-se passar por um site legítimo, e é por isso que a resistência a colisões da função de hash usada nos certificados é tão crítica.
Assinatura de código
Os sistemas operativos e as lojas de aplicações verificam se um programa vem de um autor identificado e se não foi alterado depois de empacotado. O autor assina o software com a sua chave privada, e o sistema verifica essa assinatura antes de permitir a instalação. Isto protege os utilizadores contra programas adulterados ou substituídos por terceiros. Uma colisão na função de hash usada permitiria, em teoria, fazer passar um binário malicioso como se fosse o legítimo, sob a mesma assinatura.
Documentos e contratos eletrónicos
A assinatura digital de documentos legais, faturas e contratos segue exatamente a mesma lógica de assinar um resumo com uma chave privada e verificar com a pública. É o que dá valor probatório a um contrato assinado eletronicamente, e é também onde o cenário da colisão é mais intuitivo: assinar um contrato inofensivo e ficar vinculado a um malicioso é precisamente o tipo de fraude que uma função de hash sólida impede.
Resumo
Uma assinatura digital combina uma função de hash com um par de chaves assimétricas para provar, de uma só vez, autoria e integridade. Assina-se o resumo da mensagem com a chave privada e verifica-se com a chave pública, comparando o resumo recuperado com o resumo calculado de novo. Como tudo assenta no resumo, a função de hash tem de ser resistente a colisões; caso contrário, uma assinatura sobre um documento pode valer sobre outro, como o SHAttered demonstrou para o SHA-1. Para situar as assinaturas no conjunto mais amplo das ferramentas criptográficas, veja o artigo central de criptografia.
Perguntas frequentes
Uma assinatura digital cifra a mensagem?
Não. A mensagem permanece legível. A assinatura é um acréscimo que prova quem a enviou e que não foi alterada. Confidencialidade e assinatura são objetivos distintos: se também se quiser esconder o conteúdo, cifra-se a mensagem à parte.
Por que se assina o resumo em vez do documento inteiro?
Por eficiência e robustez do esquema. A operação de chave é relativamente lenta, e o resumo é curto e de tamanho fixo, o que torna a assinatura rápida independentemente do tamanho do documento. Desde que a função de hash seja resistente a colisões, assinar o resumo é tão seguro como assinar o documento completo.
O que acontece se a função de hash usada for quebrada?
A segurança da assinatura fica comprometida. Se um atacante conseguir produzir dois documentos com o mesmo resumo, uma assinatura válida sobre um vale sobre o outro. Foi por isso que a colisão prática do SHA-1, demonstrada pelo SHAttered, levou à sua substituição pelo SHA-256 em assinaturas e certificados.




