Parte III - Assinatura Digital

Na primeira parte desta série, introduzi o assunto criptografia. Na segunda parte, falei um pouco sobre criptografia assimétrica, e suas vantagens e desvantagens. Continuando com minha abordagem não técnica, hoje irei começar a falar um pouco sobre uma aplicação importante daquilo que estudamos. A assinatura-digital.

Hash, ou Resumo Criptográfico

Dentro da criptografia, existem algumas funções além da cifragem e decifragem, sobre as quais já comentei nos outros posts. Uma delas, muito importante para o assunto que tratarei hoje, é a chamada função hash, ou, em bom português, resumo.

Uma função hash é uma função que pega uma mensagem de qualquer tamanho, e converte ela num número aparentemente aleatório, de tamanho fixo. A mesma mensagem sempre resultará no mesmo hash, não importa onde e quando você utilizar a função (desde que, é claro, seja a mesma função hash. Existem várias funções hash, algumas das mais utilizadas hoje são a MD5, a SHA-1 e a SHA-256).

É claro que, se o número é de tamanho fixo, e se a mensagem é maior que o número, necessariamente dados vão ser “jogados fora” na hora de calcular o hash. Ou seja, não tem como você obter a mensagem original a partir de um hash. Por isso, muita gente usa o hash pra armazenar senhas de websites no banco de dados, por exemplo. “Como, se não dá pra obter a senha de volta?”. Elementar, caro Holmes: O que se faz é armazenar o hash da senha. Quando você informa sua senha no login, o site gera o hash de novo, e compara os hashes, não as senhas. Se forem iguais, a senha deve ser igual. Mas se algum cracker invadir o servidor e roubar o banco de dados, ele vai ver apenas hashes, e não senhas. Isso tem um pequeno problema, mas vou deixar pra comentar isso mais no final.

A Assinatura Digital

Uma aplicação muito mais interessante (na minha opinião) do hash é a assinatura digital. Quando você assina um documento, na vida real, com caneta e sua mão, você garante a autenticidade daquele documento, certo? Ou seja, se a assinatura é sua, você está ciente do conteúdo do documento. Mas falta uma coisa: integridade. Quem garante que nada foi adicionado ao documento depois que você assinou ele? Se você assina um cheque em branco, qualquer coisa que for preenchida nele depois será paga, não importa se é o que você queria que fosse pago ou muito mais. Para contratos, o que se faz é autenticar e registrar o documento, em cartório, e emitir várias vias do mesmo documento. Se alguém aduleterar o documento, o cartório pode provar qual é o original.

Na assinatura digital, aquela feita utilizando recursos criptográficos sobre documentos eletrônicos,  tanto a autenticidade quanto a integridade são garantidas. Vamos ver como funciona:

Suponha que você tem uma mensagem, que quer assinar, no seu computador. Você primeiro gera um hash (resumo) dessa mensagem. Depois cifra esse hash com sua chave privada (lembra da criptografia assimétrica? Não? Então leia de novo a parte 2!). Aí você anexa este hash cifrado na sua mensagem, e manda ela ao destinatário.

O que vai acontecer? Como vimos na parte 2, quando alguém cifra algo usando a chave privada, significa que todo mundo pode decifrar essa mensagem. Não tinha mostrado nenhuma utilidade pra isso ainda, mas agora você vai entender: O destinatário, recebendo a mensagem e o hash cifrado, pode decifrar o hash com a chave pública do remetente, a sua chave pública. Assim, ele sabe que foi você que assinou, e passa a ter certeza da autenticidade, pois você é a única pessoa no mundo que conhece a chave privada, então só você poderia ter cifrado aquele hash. Ele vai obter um hash, e ele mesmo vai gerar um novo hash a partir da mensagem que recebeu. Ele compara o hash que você mandou cifrado, com o hash que ele acabou de gerar, e vê se são iguais. Desta forma, agora além da autenticidade, ele pode ter certeza da integridade da mensagem. Simples não? Aí vai uma figura ilustrando essa idéia (a chave vermelha é a chave privada do remetente, a verde é a pública):

Colisão de Hash

Uma das questões importantes dos hashes é a chamada colisão de hashes. Se você parar pra pensar, o fato do hash ter tamanho fixo, mas o número de mensagens ser infinito, significa que necessariamente existem diferentes mensagens que tem o mesmo hash. Ou seja, levando para fins práticos, é possível que duas senhas diferentes tenham o mesmo hash, e por isso, para acessar a conta do Fulano você possa usar a senha do Sicrano. Ou pior. Você pode assinar um documento digital que é apenas um email para um amigo. Mas o hash deste email é justamente o mesmo hash de um texto de contrato que passa todo seu dinheiro para uma determinada pessoa. E na prática, isso significa que se eu colocar a assinatura digital do email anexa ao contrato, todo mundo vai achar que a assinatura foi mesmo feita sobre o contrato. Eu, heim! Esta técnica, de tentar obter mensagens diferentes que tem o mesmo hash, é o que é chamado de colisão de hash. A figura abaixo demonstra este ataque:

Mas calma, não entre em pânico. Pensando nisso, mensagens de hash são virtualmente aleatórias. Um bom hash é feito de tal forma que seu comportamento é imprevisível, ou seja, você não deve conseguir montar uma mensagem querendo chegar num determinado hash, o que é essencial para o sucesso do ataque. E mais do que isso, um bom hash é aquele que, modificando 1 bit na mensagem (lembre-se que o computador, tudo são números, e números representados na forma de bits 0 e 1), metade dos bits do hash mudam. Ou seja, é praticamente impossível, com boas funções hash, obter uma colisão que tenha alguma utilidade prática.

O ataque é ainda eficiente para descobrir senhas, já que nesse caso não interessa descobrir a senha de verdade, e sim apenas uma senha que gere o mesmo hash. Não importa se a senha que você vai achar é a senha de verdade, (ou seja, a data de nascimento do usuário ;)), ou se for $CNSDLKU@$*() mas tenha o mesmo hash. Pois ambas permitem o acesso ao site do mesmo jeito. É por isso que cada vez mais as funções de hash simples estão sendo substituídas por funções de hash com um negócio chamado salt, que faz com que o hash seja diferente com salts diferentes e isso dificulte bastante o processo de colisão.

Mas para o caso de assinaturas digitais, se uma colisão for encontrada, é muito provável que somente uma das mensagens tenha sentido. As demais provavelmente não passarão de um amontoado de caracteres aleatórios, sem sentido algum. E mesmo esse amontoado de caracteres é difícil de encontrar. Por isso, neste caso, não há motivo para preocupação, desde que você esteja utilizando sempre boas e modernas funções hash.

Claro, você deve considerar que toda função hash um dia será considerada fraca. Por exemplo o MD5, que por muito tempo utilizado, hoje já tem exemplos de colisões úteis. Ou seja, uma assinatura tem prazo de validade, e é preciso um jeito de manter a validade dessa assinatura por muito tempo - de preferência, pra sempre. A boa notícia é que existe sim um jeito de fazer isso, e se chama carimbo de tempo, que é uma técnica que permite ter certeza sobre quando uma assinatura foi feita - mesmo que no futuro a função de hash tenha sido quebrada, você saberá que quando a assinatura foi feita ela ainda era segura, e por isso pode confiar na assinatura. Mas aí já estaremos indo longe demais para este artigo. Fica para um próximo.

Considerações Finais

A assinatura digital está em uso crescente no Brasil. A Justiça está migrando todos seus processos para meios eletrônicos, tudo sendo assinado eletrônicamente. O presidente Lula assina decretos das suas férias usando assinatura digital. E em breve, você também estará utilizando isso. No próximo artigo, explicarei como se pode fazer para ter certeza de que uma chave realmente pertence a uma determinada pessoa.

E como sempre, se ficaram dúvidas... Pergunte!

Comments