Comunicação a Distância
Desde que interações entre pessoas ocorrem a distância -- seja
via sinais de fumaça, pombos, correios ou redes de computadores --
temos dificuldades de saber com quem estamos falando e para se
assegurar da privacidade da comunicação. No mundo dos nosso
ancestrais nas savanas de Africa era fácil manter uma mensagem
confidencial, era só uma questão de falar baixo. Os nossos
cérebros, os nossos comportamentos e as nossas intuições não
evoluíram para viver num mundo de interações sociais a
distância. Evoluímos para ser extremamente bons em reconhecer a
identidade da pessoa com quem estamos interagindo, uma coisa
essencial em todas as interações sociais. Mas em comunicação à
distância não dispomos da rica linguagem corporal necessária para
identificar alguém e estabelecer uma relação de confiância. Nas
condições de comunicação a distância não podemos mais confiar nas
nossas estratégias que evoluíram para avaliar a identidade e até
honestidade do nosso interlocutor. Precisamos de tecnologia.
Criptografia pode ser usado para assegurar a privacidade, a
integridade da comunicação e da autenticidade da identidade de
quem está no outro lado do canal de comunicação. São três
objetivos distintos. Para manter privacidade a comunicação deve
ser encriptada. Existem outras técnicas criptográficas para se
assegurar da proveniência da mensagem e prevenir que elas são
alteradas por partes não autorizadas. Em geral a impressão que
temos de criptografia é que encriptar é a função principal dela,
mas na verdade na grande maioria dos casos é autenticação
(da mensagem e da identidade) é muito mais importante. Deste
texto, a lição mais importante é que encriptar sem
autenticar não tem valor. Se você não sabe com quem está
se comunicando, é melhor nem tentar encriptar as suas mensagens
porque a sua segurança é ilusório.
Neste post somente discuto criptografia "simétrico", que supõe
que uma chave secreta compartilhada existe entre as partes. A
distribuição destas chaves hoje em dia muitas vezes é feito usando
criptografia assimétrica (ou, "de chave pública") que talvez
tratarei mais tarde.
Autenticação simples e segredos compartilhados
A maneira mais simples de convencer alguém no outro lado do
canal da sua identidade é mostrar que vocês compartilham um
segredo. Isto pode ser feito por meio de
- uma coisa que você sabe: um senha como senha1 por exemplo;
- uma coisa que você é: os seus impressões digitais por exemplo;
- uma coisa que você possui: uma chave ou cartão por exemplo.
Para um segredo compartilhado se manter secreto obviamente este
obviamente deve ser difícil de roubar ou adivinhar. Onde guardar
os seus segredos? Um segredo guardado na sua cabeça é chamado de
senha. A vantagem de senhas é que ninguém pode roubar e que sempre
está contigo.
Para ser difícil de adivinhar o segredo tem que ser de uma
certa complexidade. Mas senhas guardadas na sua cabeça sofrem das
limitações gravíssimas do seu cérebro: como vai se lembrar de uma
senha do tipo "@df$8hdghujtrffhced#$"? [Para especialistas: é
impossível guardar os 128 bits de entropia (complexidade)
necessários para segurança adequada na sua cabeça.] Por outro
lado, senhas simples são muito fácil de adivinhar, é só começar
com "senha", "1234", "senha1" e continuar tentando com todas as
palavras do dicionário, com alguns pre- e pos-fixos até encontrar
a senha correta.
Uma solução perfeita não existe, mas uma estratégica boa para
guardar uma senha é guardar uma parte (simples) na sua cabeça e
uma outra parte num papelzinho na sua carteira.
Segredos compartilhados em geral precisam ser mais complexos do
que senhas. Para guardar um segredo de 128 bits como
"2de1afe3b45b656eade98034daaa123a" o seu próprio computador parece
um bom lugar. Infelizmente computadores são notoriamente
inseguros, infestado por vírus, troianos, etc. que podem roubar o
segredo. Um smartcard (como o seu cartão da USP) parece
interessante, mas como fazer o interface entre o segredo guardado
lá e o software que roda o algoritmo? Talvez precisamos colocar os
algoritmos de criptografia na própria smartcard. Está ficando um
dispositivo cada vez mais parecido com um computador, com todos os
seus problemas. Também, um smartcard ou token é fácil de roubar
ou perder.
Em suma, para ter um sistema seguro, todos as partes do sistema
tem que ser seguro. Não adianta colocar uma grande porta de ferro
para proteger uma barraca de lona. Seja com for, em seguida vou
descrever como poderia construir a porta de ferro.
Encriptar: algoritmos e chaves
Se usar uma senha para se identificar através de um canal de
comunicação, como vai evitar o roubo da senha por qualquer um
que está monitorando este canal? De uma maneira geral,
precisamos de encriptação para manter a confidencialidade da
comunicação. Veja a Alícia querendo falar com Roberto.
O malvado Everton fica sabendo de tudo:
O que fazer se Alícia e Roberto precisam se comunicar sobre um
canal não seguro como cartões postais ou a internet? Precisamos
encriptar a mensagem por meio de uma cifra
Uma cifra
é um algoritmo para encriptar uma mensagem. É uma receita, um
conjunto de regras, que transformam a mensagem original. Segredos
pequenos e simples são mais simples de guardar. É por isso que o
conjunto de regras, os algoritmos de encriptação, sempre são
públicos e a segurança somente depende da chave, um número
pequeno que junto com o algoritmo determina a encriptação (veja
também o Princípio de Kerckhoffs em
baixo).
A chave, um segredo pequeno, é usado para guardar o segredo
grande, a mensagem. É preciso saber a chave (e o algoritmo) para
decifrar a mensagem encriptada. Para criptografia simétrico a
mesma chave é usado tanto para encriptar a mensagem como para
decriptar ela. Isto significa que tanto quem manda como o receptor
da mensagem tem que ter acesso à chave e que temos que distribuir
as chaves de uma maneira segura, por algum outro canal. Mas
avançamos porque é mais fácil distribuir e guardar segredos
pequenos (as chaves) do que segredos grandes (as mensagens).
Integridade da Mensagem
Encriptar a sua mensagem não é suficiente para manter um canal
de comunicação seguro. O malvado Everton ainda pode mudar a
mensagem, o que pode ser altamente prejudicial. O recipiente
precisa se assegurar da integridade da mensagem e da identidade de
quem mandou. A solução para ambas os problemas é um MAC
("Message
Authentication Code"). É um código ou número, um espécie de
impressão digital da mensagem, que é mandado junto com a
mensagem. Somente quem está de posse da chave secreta pode fazer o
MAC e somente quem está de posse da mesma chave pode
verificá-lo.
Um MAC pode ser feito por exemplo usando
um hash. Um
hash é uma função que transforma uma mensagem numa seguência de
bytes de uma maneira imprevisível. Veja por exemplo o hash chamado
de SHA-1 de duas mensagens parecidas:
sha1("senha") = 7751a23fa55170a57e90374df13a3ab78efe0e99
sha1("senha1") = adddc25f41289bb0e9da98742a94a861560c1c37
Ou seja, uma pequena mudança na entrada leva a saídas
completamente differente. Um MAC simples podia então ser
sha1(KM+mensagem). O malvado Everton não pode mudar
nenhuma letra da mensagem sem que o MAC correto mude
completamente. E para quem não conhece a chave secreta KM é
inviável desbrobrir qual MAC corresponde à mensagem falsa. [Este
MAC simples não deve ser usado em sistemas reais por razões
complicadas ("length extension attacks", veja Ferguson e Scheier,
2003)]
Vale a pena ressaltar mais uma vez o fato talvez surpreendente
que a confidencialidade e a autenticidade da mensagem
são independentes e tem soluções (encriptação e o MAC)
diferentes. A primeira vista parece suficiente encriptar a
mensagem. Afinal, o malvado Everton pode mudar a mensagem
encriptado, mas sem ter a chave secreta a mensagem decriptado não
vai fazer sentido. Mas mesmo mensagens sem sentido podem fazer
danos, se Roberto assume erroneamente que vem de Alícia. Uma outra
razão porque é útil separar confidencialidade e autenticação é
porque assim podemos usar algoritmos especializados e otimizados
para cada função. Para uma terceira razão, imagine o caso onde
encriptar a mensagem é indesejável (talvez por razões
legais). Mesmo assim Roberto gostaria ser capaz de se assegurar
que a mensagem veio de Alícia. Com as funções confidencialidade e
autenticidade implementados por algorimos diferentes isto é
possível.
Autenticação deve ser considerado mais importante do que a
encriptação. Pense assim: que mal o malvado Everton pode fazer
sabendo do conteúdo da comunicação? Agora, que maldades ele
poderia fazer se pudesse manipular as mensagens?
O Canal Seguro
Um canal de comunicação que garante a privacidade, a
integridade e a autenticidade da Alícia é chamado de
"seguro". Basicamente combina as duas funcionalidades descritos
acima. Primeiro a Alícia calcula um MAC (usando uma chave secreta
KM) e depois encripta a mensagem e o MAC junto (usando uma outra
chave secreta, geralmente). Roberto decripta e verifique a
integridade da mensagem.
Não é nada trivial implementar um canal seguro. Por exemplo,
para evitar ataques onde Everton usa mensagem antigos ("replay
attacks") é necessário numerar as mensagens, ou usar um "nonce",
um número usado exatamente uma vez durante a existência do
canal. Um outro exemplo é que a chave compartilhada deve valer
por uma duração limitado, primeiro para evitar que o Everton
retransmite mensagens de uma sessão anterior e segundo porque
chaves de uma maneira geral devem ter uma vida curta (se uma
"chave de sessão" for comprometida, pelo menos as outras sessões
se mantem seguras). Os algoritmos de encriptação e do MAC devem
ser usados de uma determinada maneira. Assim tem muitas detalhes
que podem comprometer a segurança do canal.
Princípio de Kerckhoffs
É
um princípio
básico de criptografia que a segurança do sistema deve
depender somente do fato que a chave é segredo. O algoritmo deve
ser público e transparente. Este princípio é atribuído
a Auguste
Kerckhoff, um estudioso Holandês de línguas, trabalhando na
França no século 19. Uma razão é que um segredo de tamanho pequeno
é muito mais fácil de guardar do que um segredo grande (o
algoritmo). Quando um sistema criptográfico é usado por mais do
que alguns poucos participantes, é ingênuo pensar que o algoritmo
pode ficar um segredo. O fato é que é muito mais simples esconder
(e distribuir entre os participantes) chaves do que sistemas de
criptografia inteiros.
Mas a razão principal é que sistemas, protocolos e algoritmos
públicos podem ser submetidas a revisão por pares para descobrir
eventuais falhas. Sistemas e algoritmos secretos são revisados
somente por um grupo necessariamente pequeno. Com exceção do NSA,
é extrememamente improvável que um grupo particular vai produzir
sistemas melhor do que os públicamente revisado e testados.
Segue que nunca deve inventar os seus próprios algoritmos ou
sistemas de segurança. Sempre deve usar algoritmos públicos e
bem-testados.
Distribuição das chaves
Nada falamos ainda sobre como Alícia e Roberto conseguiram o
segredo compartilhado. O maior problema de criptografia simétrica
é justamente a distribuição segura das chaves. Se temos N pessoas
querendo se comunicar deve ter N(N-1)/2 chaves para que cada par
de usuários possam se comunicar seguramente. Por exemplo, se um
grupo de 10 pessoas querem organizar reuniões sem que as
autoridades saibam é preciso distribuir de alguma forma segura 45
chaves secretas. Para 100 pessoas são 4950 chaves. Para
computadores em rede, um possível solução é usar um servidor de
confiânca e online que distribui chaves. Kerberos é um protocolo
que faz isto.
Este tipo de solução requer uma coordenação prévia entre as
partes. Existem soluções também para partes que nunca se
encontraram ou conheceram antes. Por incrível que parece, existe
uma sequência de troca de mensagens (agora conhecido como
"Diffie-Hellman") que acaba com Alícia e Roberto tendo o mesmo
número, sem que o malvado Everton, que escutou a conversa toda,
fica sabendo. Também é possível fazer criptografia onde as chaves
secretas não precisam ser as mesmas e compartilhadas. Em
criptografia de chave pública Alícia pode manter um segredo e dar
uma chave pública a Roberto que então pode ser comunicar
seguramente com Alícia. Mas os mesmos problemas de autenticação e
identidade surgem, como veremos num próximo post.
Referencias
Applied Cryptography, Bruce Schneier (1996) e Practical
Cryptography, Niels Ferguson e Bruce Schneier (2003) são clássicos
da área. O livro de Ross Anderson
sobre engenharia
de segurança é muito bom e
o FAQ antigo
do RSA vale a pena conferir. Veja
também alguns links
relacionados com criptografia que colecionei.
Este texto e o arquivo das imagens estão disponível para remix (cc-by).
Esta mensagem está sob a licença CreativeCommons Atribuição.