Kerberos - Cena IV

Projetando um sistema de autenticação, um diálogo em quatro cenas

Manhã seguinte na sala do Euripedes. Athena bate na porta.

Eurípedes Você está com umas manchas pretas sob os olhos essa manhã.
Athena Bem, você sabe. Outra daquelas longas noites.
Eurípedes Você resolveu o problema de renvio?
Athena Acho que sim.
Eurípedes Sente-se

Ela se senta
Athena Como de hábito, sinto que devo enunciar o problema novamente. Tickets são reusáveis dentro de um limíte de tempo. Digamos oito horas. Se alguém rouba os seus tickets e resolve reusá-los depois de expirados, nós não podemos fazer nada.
Eurípedes Esse é o problema.
Athena Nós podemos acabar com o problema se projetarmos os tickets de modo que eles não possam ser reusados.
Eurípedes Mas aí você precisará pegar um novo ticket a cada vez que você quiser utilizar um serviço de rede.
Athena Certo. Isso é só um jeitinho. (Pausa) Ahn, como posso explicar melhor? (Ela pondera por um momento.)
Tudo bem, vou enuncir o problema novamente, dessa vez em forma de requisitos. Um serviço de rede precisa estar apto a provar que a pessoa que está utilizando o ticket é a mesma pessoa para quem o ticket foi fabricado.

Deixe-me percorrer o processo de autenticação novamente e ver se consigo desenvolver um caminho apropriado para ilustrar a minha solução para esse problema.

Eu quero utilizar um certo serviço de rede. Eu acesso o serviço iniciando o programa cliente na minha estação de trabalho. O cliente envia três coisas para o servidor do serviço; meu nome, o endereço de rede da minha estação de trabalho e o ticket apropriado para o serviço.

O ticket contém o nome da pessoa para quem ele foi fornecido e o endereço de rede da estação de trabalho que aquela pessoa estava utilizando quando ele ou ela adquiriu o ticket. Ele também contém uma data de expiração em forma de tempo de vida e um selo cronológico. Todas essas informações foram criptografadas com a senha do serviço pelo Caronte.

Nosso esquema de autenticação atual se baseia nas seguintes verificações:
  • O serviço pode descriptografar o ticket?
  • O ticket expirou?
  • O nome e endereço da estação de trabalho especificado no ticket bate com o nome e o endereço da pessoa que enviou o ticket?

O que essas verificações provam? O primeiro teste verifica se o ticket veio ou não do Caronte. Se o ticket não puder ser descriptografado, ele não veio do Caronte verdadeiro. O Caronte verdadeiro precisa ter criptografado o ticket com a senha do serviço. Caronte e o serviço são as duas únicas entidades que conhecem a senha do serviço. Se o ticket descriptografar corretamente, o serviço sabe que ele veio do Caronte verdadeiro. Esse teste previne que pessoas falsifiquem tickets do Caronte.

O segundo teste verifica o tempo de vida e o selo cronológico do ticket. Se ele expirou, o serviço irá rejeitar o ticket. Esse teste bloqueia as pessoas de usarem tickets vencidos, tickets que talvez tenham sido roubados.

O terceiro teste compara o nome e o endereço do ticket do usuário com o nome e o endereço do usuário especificado dentro do ticket. Se o teste falhar, o usuário terá obtido (talvez surrupiado) o ticket de outra pessoa. O ticket será rejeitado, claro.

Se os nomes e endereços não baterem, o que estará provado? Nada. Malandros podem roubar tickets da rede, alterar o endereço da sua estação de trabalho e nome de usuário apropriadamente, e passar a mão nos recursos de outras pessoas. Como eu apontei ontem, tickets podem ser reusados, uma vez que eles não tenham expirados. Eles podem ser reusados porque um serviço não pode determinar que a pessoa enviando o ticket é realmente o legítimo dono do ticket.

O serviço não pode determinar isso porque ele não compratilha um segredo com o usuário. Veja da seguinte maneira. Se eu estou sitiada em Elsinore, você sabe, o castelo em Hamlet italic, e você pensa me ajudar, eu não penso em deixar você chegar até mim, ao menos que você forneça a senha correta. Isso é um caso onde nós dois compartilhamos um segredo. Esse é provavelmente um tipo de segredo outros procuram para chegar a quem está sitiada.

Então eu estava pensando essa noite, porque o Caronte não pode criar uma senha para legitimar o ticket do usuário para compartilhar com o serviço? O Caronte dá uma cópia dessa "chave de sessão" para o serviço, e uma cópia para o usuário. Quando o serviço recebe o ticket do usuário, ele pode utilizar a chave de sessão para testar a identidade do usuário.
Eurípedes Espere um segundo. Como o Caronte fornecerá a chave de sessão para ambas as partes?
Athena O ticket do usuário contém a chave de sessão na resposta do Caronte. Assim:

Ela rabisca o seguinte na lousa: italic

RESPOSTA DO CARONTE
[chave de sessão|ticket]


A cópia da chave de sessão do serviço vem dentro do ticket e o serviço pega a chave quando ele descriptografa o ticket. Então o ticket ficam parecido com isso:

TICKET
{chavedesessao:
nomedeusuario:
endereco:
nomedoservico:
tempodevida:
selocronologico}


Quando você quer acessar um serviço, o programa cliente que você inicia, monta o que eu chamo de AUTENTICADOR. O autenticador contém o seu nome e o endereço da sua estação de trabalho. O cliente criptografa essa informação com a chave de sessão, a cópia da chave de sessão que você recebeu quando você solicitou o ticket.

AUTENTICADOR
{nomedeusuario:endereco}
criptografado com a chave de sessão


Depois de construir o autenticador, o cliente envia ele e o ticket para o serviço. O serviço não pode descriptografar o autenticador ainda porque ele não possui a chave de sessão. Aquela chave está no ticket, então o serviço primeiro descriptografa o ticket.

Depois de descriptografar o ticket, o serviço finaliza com a seguinte informação:

  • O tempo de vida e o selo cronológico do ticket;
  • O nome do dono do ticket;
  • O endereço de rede do dono do ticket;
  • A chave de sessão.

O serviço verifica se o ticket expirou. Se tudo está correto, o serviço posteriormente utiliza a chave de sessão para descriptografar o autenticador. Se a descriptografia ocorre sem nenhum tropeço, o serviço finaliza com o nome do usuário e o endereço da rede. O serviço testa essa informação contra o nome e o endereço encontrado no ticket, E o nome e o endereço da pessoa que enviou o ticket e o autenticador. Se tudo combinar, o serviço determinou que o emissário do ticket é realmente o dono do ticket de verdade.

Athena pausa, limpa a garganta, toma um gole de café. italic

Eu creio que essa combinação chave de sessão e autenticador dão conta do problema de reuso.

Eurípedes Talvez, mas eu acho... Para quebrar essa versão do sistema, eu preciso ter a autenticador correto para o serviço.
Athena Não. Você precisa ter o autenticador E o ticket para o serviço. O autenticador não vale nada sem o ticket, porque o serviço não pode descriptografar o autenticador sem primeiramente ter a chave de sessão apropriada, e o serviço não pode pegar a chave de sessão apropriada sem antes descriptografar o ticket.
Eurípedes Certo, entendo, mas você não disse que quando um programa cliente contactar o servidor, ele envia o ticket e o autenticador juntos?
Athena Sim, acho que eu disse isso.
Eurípedes Se é isso que realmente acontece, o que previne que eu roube o ticket e o autenticador ao mesmo tempo? Eu tenho certeza que posso fazer um programa para executar essa tarefa. Se eu tenho o ticket e o autenticador, eu acredito que eu possa utilizar os dois uma vez que o ticket não expirou. Eu só preciso alterar o enderço da minha estação de trabalho e o nome de usuário apropriadamente. Certo?
Athena (mordendo os lábios) Certo. Que desalento.
Eurípedes Espere, espere, espere. Vejamos, o programa cliente constroi o autenticador, então o envia com o ticket para o serviço. Você copia ambos, ticket e autenticador, enquanto eles se movem da minha estação de trabalho para o servidor. Porém o ticket e o autenticador chegam ao servidor antes que você possa enviar a suas cópias. Se o autenticador só pode ser utilizado uma vez, a sua cópia dele não é boa, e você dançou quando você tentou reusar o ticket e o autenticador.

Nossa, que alívio! Então o que precisamos inventar é um jeito de fazer o autenticador usável por uma vez.

Sem problema. Vamos somente colocar um tempo de vida e um selo cronológico nele. Suponha que cada autenticador tenha um tempo de vida de alguns minutos. Quando você quer utilizar um serviço, o seu programa cliente monta o autenticador, estampa-o com o tempo corrente, então envia ele e o ticket para o servidor.

O servidor recebe o ticket e o autenticador e toca o negócio. Quando o servidor descriptografa o autenticador, ele verifica o tempo de vida do autenticador e o selo cronológico. Se o autenticador não tiver expirado, e tudo o mais está correto, o servidor te considera autenticada.

Suponha que eu copie o autenticador e o ticket quando eles cruzam pela rede. Eu preciso mudar o enderço da rede na minha estação de trabalho e o meu nome de usuário, e eu preciso fazer isso em alguns minutos. É um trabalho e tanto, que realmente acho que não é possível. Ao menos que...

Bem, aqui está um problema em potencial. Suponha que ao invés de copiar o ticket e o autenticador enquanto eles trafegam da estação de trabalho para o servidor, eu copie o pacote original do ticket que vem do Caronte, o pacote que você recebe quando você solicita um ticket para o Caronte.

Esse pacote, pelo que me lembro, possui duas cópias da chave de sessão nele: um para você e um para o serviço. O que é para o serviço, está oculto no ticket e eu não posso pegá-lo, mas e sobre o outro, o que você usa para montar o autenticador?

Se eu posso pegar aquela cópia da chave de sessão, eu posso construir o meu próprio autenticador, e se eu posso construir o meu próprio autenticador, eu quebro o sistema.
Athena Eu andei pensando nisso essa noite, porém eu tracei o processo de aquisição de tickets e achei que não seria possível roubar os autenticadores dessa maneira.

Você se senta na sua estação de trabalho e utiliza o programa kinit para pegar o seu ticket-concessor de ticket. o Kinit pegunta pelo seu nome de usuário e após você entrá-lo, o kinit envia o nome ao Caronte.

O Caronte utiliza o seu nome para procurar a sua senha, então prossegue na construção do ticket-concessor de ticket para você. Como parte desse processo, o Caronte cria a chave de sessão que você irá compartilhar com a concessionária de tickets. O Caronte coloca a cópia da chave de sessão no ticket-concessor de ticket e coloca a sua cópia no pacote do ticket que você está para recebê-lo. Mas antes dele enviar esse pacote para você, o Caronte criptografa tudo com a sua senha.

O Caronte envia o pacote através da rede. Alguém pode copiar o pacote assim que ele vai, mas eles não podem fazer nada com isso, porque ele foi criptografado com a sua senha. Especificamente, ninguém pode roubar a chave de sessão do ticket-concessor.

O Kinit recebe o pacote do ticket e solicita para você a senha, a qual você informa. Se você entrar a senha correta, o kinit pode descriptografar o pacote e te dar a cópia da chave de sessão.

Agora que você cuidou da questão do kinit, você quer pegar o seu e-mail. Você inicia o programa cliente de correio. Esse programa procura pelo ticket de serviço de correio e não acha um (afinal de contas, você ainda não tentou pegar o seu correio). O cliente precisa utilizar o ticket-concessor de ticket para solicitar à concessionária de tickets, por um ticket para o serviço de correio.

O cliente monta um autenticador para o ticket-concessor da transação e criptografa o autenticador com a sua cópia da chave de sessão do ticket-concessor. O cliente então envia ao Caronte o autenticador, o ticket-concessor de ticket, seu nome, endereço da sua estação de trabalho, e o nome do serviço de correio.

A concessionária de tickets recebe isso tudo e executa uma checagem da autenticação. Se tudo corre bem, a concessionária de tickets monta um ticket de serviço de correio, e durante esse processo, cria uma chave de sessão para você compartilhar com o serviço de correio.

A concessionária de tickets agora prepara um pacote do ticket para enviar de volta para a sua estação de trabalho. O pacote contém o ticket e a sua cópia da chave de sessão do serviço de correio. Mas antes que ele envie o pacote, a concessionária de tickets criptografa o pacote com a sua cópia da chave de sessão do TICKET-CONCESSOR. Tendo feito, o pacote é enviado.

Dessa maneira chega o pacote do serviço de correio à galope pela rede. Suponha que um curupira na rede copie-o enquanto ele trafega. O curupira está sem sorte porque o pacote está criptografado com a chave de sessão do ticket-concessor; você e a concessionária de tickets são as únicas entidades que sabem essa chave. Desde que o curupira não pode descriptografar o o pacote do ticket de correio, o curupira não pode descobrir a CHAVE DE SESSÃO DO CORREIO. Sem essa chave de sessão, o curupira não pode utilziar qualquer ticket de serviço do correio que você pode enviar sub-sequentemente pela rede.

Então acho que estamos seguros. O que você acha?
Eurípedes Talvez.
Athena Talvez! É só isso que você sabe dizer?
Eurípedes (rindo) Não se aborreça. Você já deveria ter se acostumado com o meu jeito. Eu acho que em partes sou eu e em partes você que passou metade da noite em claro.
Athena Pffff!
Eurípedes Tá bom, três quartos da noite. Mas de fato, o sistema está começando a se tornar aceitável. Essa questão da chave de sessão resolve um problema que eu andei pensando a noite passada; o problema da autenticação mútua.

Pausa

Se incomoda se eu falar um minutinho?
Athena (concorda com desdém) Fique à vontade.
Eurípedes Você é tão gentil. (Eurípedes pigarreia para limpar a garganta) A noite passada, enquanto visões de chaves de sessão e autenticadores dançavam na sua cabeça, eu estava tentando achar novos problemas no sistema, e encontrei um que pensei que fosse um tanto quanto sério. Irei ilustrá-lo através do seguinte cenário.

Suponha que você está cansada do seu trabalho atual e tenha decido que é melhor para o seu interesse sair. Você quer imprimir o seu curriculum na super impressora da empresa, assim os empregadores em potencial poderão tomar nota da sua classe.

Então você dá o comando de impressão e direciona-o para enviar o curriculum para o servidor de impressão apropriado. O comando pega o ticket de serviço próprio, se você ainda não tive-lo, então envia o ticket em seu nome para o servidor de impressão apropriado. Ao menos é para onde você pensa que ele foi enviado. Mas você não sabe de fato se a requisição foi enviada para o servidor de impressão correto.

Suponha que algum hacker inescrupuloso, digamos o seu chefe, tenha ferrado o sistema de maneira que ele redirecione a suas requisições e os seus tickets para o servidor de impressão na sua sala. O seu servidor de impressão não está nem aí com ticket ou com o seu conteúdo. Ele joga fora o ticket e envia uma mensagem para a sua estação de trabalho indicando que o ticket passou na inspeção e que o servidor está pronto para imprimir o seu trabalho. O comando de impressão envia o trabalho para o servidor de impressão fraudulento e o inimigo fica com o seu curriculum.

Eu vou estabelecer o problema ao contrário. Sem chaves de sessão e autenticadores, o Caronte pode proteger os seus servidores de usuários falsos, mas não pode proteger os usuários de falsos servidores. O sistema precisa de um jeito de os programas cliente autenticarem o servidor antes de enviar informações sensíveis para o serviço. O sistema precisa permitir autenticação mútua.

Porém a chave de sessão resolve esse problema uma vez que você projetou os programas cliente apropriadamente. De volta ao cenário do servidor de impressão. Eu quero um programa cliente de impressão que tenha certeza que o serviço para onde está sendo enfiado o trabalho seja o serviço legítimo.

Aqui está o que o programa faz. Eu entro o comando de impressão e dou o nome do arquivo, o nome do meu curriculum. Digamos que eu tenha um ticket de impressão de serviço e uma chave de sessão. O programa cliente utiliza a chave de sessão para montar o autenticador, então envia o autenticador e o ticket para o "suposto" servidor de impressão. O cliente NÃO envia o curriculum ainda, ele espera por uma resposta do serviço.

O serviço verdadeiro recebe o ticket e o autenticador, descriptografa o ticke e extrai a chave de sessão, então utiliza a chave de sessão para descriptografar o autenticador. Isso feito, o serviço roda todos os testes de autenticação apropriados.

Assuma que os testes confirmem a minha identidade. Agora o servidor prepara um pacote de resposta para que ele possa provar a sua identidade para o programa cliente. Ele usa a sua cópia da chave de sessão para criptografar o pacote de resposta, então envia o pacote para o cliente que está aguardando.

O cliente recebe o pacote e procura descriptografá-lo com a minha cópia da chave de sessão. Se o pacote descriptografa corretamente e aceita a mensagem de resposta do servidor, o meu programa cliente sabe que o servidor que criptografou o pacote é o servidor real. Agora o cliente envia o arquivo do curriculum para o serviço de impressão.

Suponha que o meu chefe tenha ferrado com o sistema de maneira que a sua impressora queira se passar por uma que eu queira. O meu cliente envia o autenticador e o ticket para o "serviço de impressão" e espera pela resposta. O serviço de impressão falso não pode gerar a resposta correta proque ele não pode descriptografar o ticket e pegar a chave de sessão. O meu cliente não vai enviar o trabalho ao menos que ele receba a resposta correta. Eventualmente, o cliente pode desistir de esperar e sair. O meu trabalho de impressão não finalizou, mas ao menos o meu curriculum não foi parar na mesa do inimigo.

A sua vez agora. Eu acho que nós temos bases sólidas para implementar o Serviço de Autenticação Caronte.
Athena Talvez. Além do que, eu não gosto do nome "Caronte".
Eurípedes Você não? Desde quando?
Athena Eu nunca gostei dele, porque o nome não faz sentido. Eu estava conversando com o meu Tio Hades sobre isso um dia desses, e ele sugeriu outro nome , o nome daquele cão de guarda de três cabeças.
Eurípedes Ah, você fala do "Cerberus".
Athena Morda a sua lingua Rip! "Cerberus", onde já se viu...
Eurípedes Err, não éra esse o nome?
Athena Sim, se você fosse um Romano! Eu sou linda deusa Grega, ele é um cão de guarda Grego e o seu nome é "Kerberos", "Kerberos" com K.
Eurípedes Tudo bem, tudo bem, não solte raios. Eu ficarei com o nome. Aliás, é um belo desafio para ele. Adios Caronte e olá Kerberos.




------------------
Epílogo

---------------------
Revisões
Traduzido em 23/10/2007 20:20 em aprox. 3:30 hr
Editado e publicado em 23/10/2007 20:50 em aproximadamente 0:45 hr

Popular posts from this blog

Atom - Jupyter / Hydrogen

Design Patterns

Robson Koji Moriya disambiguation name