Nota: eu escrevi minha resposta original muito apressadamente, mas desde então, isso se transformou em uma pergunta / resposta bastante popular, então eu a expandi um pouco e a tornei mais precisa.
Capacidades TLS
"SSL" é o nome mais frequentemente usado para se referir a este protocolo, mas SSL refere-se especificamente ao protocolo proprietário projetado pela Netscape em meados dos anos 90. "TLS" é um padrão IETF baseado em SSL, portanto, utilizarei o TLS na minha resposta. Hoje em dia, as chances são de que quase todas as suas conexões seguras na Web estejam realmente usando TLS, não SSL.
O TLS possui vários recursos:
- Criptografe os dados da camada do aplicativo. (No seu caso, o protocolo da camada de aplicativo é HTTP.)
- Autentique o servidor no cliente.
- Autentique o cliente no servidor.
# 1 e # 2 são muito comuns. # 3 é menos comum. Você parece estar se concentrando no # 2, então eu explicarei essa parte.
Autenticação
Um servidor se autentica em um cliente usando um certificado. Um certificado é um blob de dados [1] que contém informações sobre um site:
- Nome do domínio
- Chave pública
- A empresa proprietária
- Quando foi emitido
- Quando expirar
- Quem a emitiu
- Etc.
Você pode obter confidencialidade (nº 1 acima) usando a chave pública incluída no certificado para criptografar mensagens que só podem ser descriptografadas pela chave privada correspondente, que deve ser armazenada com segurança nesse servidor. [2] Vamos chamar esse par de chaves de KP1, para não ficarmos confusos mais tarde. Você também pode verificar se o nome de domínio no certificado corresponde ao site que está visitando (nº 2 acima).
Mas e se um adversário pudesse modificar pacotes enviados para e a partir do servidor e se esse adversário modificasse o certificado que lhe foi apresentado e inserisse sua própria chave pública ou alterasse outros detalhes importantes? Se isso acontecesse, o adversário poderia interceptar e modificar qualquer mensagem que você pensasse estar criptografada com segurança.
Para evitar esse ataque, o certificado é criptograficamente assinado pela chave privada de outra pessoa, de forma que a assinatura possa ser verificada por qualquer pessoa que possua a chave pública correspondente. Vamos chamar esse par de chaves de KP2, para deixar claro que essas não são as mesmas chaves que o servidor está usando.
Autoridades de certificação
Então, quem criou o KP2? Quem assinou o certificado?
Simplificando um pouco, uma autoridade de certificação cria o KP2 e eles vendem o serviço de usar sua chave privada para assinar certificados para outras organizações. Por exemplo, eu crio um certificado e pago uma empresa como a Verisign para assiná-lo com sua chave privada. [3] Como ninguém além da Verisign tem acesso a essa chave privada, nenhum de nós pode forjar essa assinatura.
E como eu pessoalmente pegaria a chave pública no KP2 para verificar essa assinatura?
Bem, já vimos que um certificado pode conter uma chave pública - e os cientistas da computação adoram recursão -, por que não colocar a chave pública KP2 em um certificado e distribuí-la dessa maneira? Isso parece um pouco louco no começo, mas na verdade é exatamente assim que funciona. Continuando com o exemplo da Verisign, a Verisign produz um certificado que inclui informações sobre quem eles são, que tipos de coisas eles têm permissão para assinar (outros certificados) e sua chave pública.
Agora, se eu tiver uma cópia desse certificado da Verisign, posso usá-lo para validar a assinatura no certificado do servidor do site que quero visitar. Calma né ?!
Bem, não tão rápido. Eu tive que obter o certificado da Verisign de algum lugar . E se alguém falsificar o certificado Verisign e colocar sua própria chave pública lá? Em seguida, eles podem forjar a assinatura no certificado do servidor e voltamos ao ponto em que começamos: um ataque man-in-the-middle.
Cadeias de certificados
Continuando a pensar recursivamente, é claro que poderíamos introduzir um terceiro certificado e um terceiro par de chaves (KP3) e usá-lo para assinar o certificado Verisign. Chamamos isso de cadeia de certificados: cada certificado da cadeia é usado para verificar o próximo certificado. Espero que você já possa ver que essa abordagem recursiva é apenas tartarugas / certificados até o fim. Onde isso pára?
Como não podemos criar um número infinito de certificados, a cadeia de certificados obviamente precisa parar em algum lugar , e isso é feito incluindo um certificado na cadeia que é autoassinado .
Farei uma pausa por um momento enquanto você pega os pedaços de matéria cerebral da sua cabeça explodindo. Auto-assinado ?!
Sim, no final da cadeia de certificados (também conhecida como "raiz"), haverá um certificado que usa seu próprio par de chaves para se autenticar. Isso elimina o problema de recursão infinita, mas não corrige o problema de autenticação. Qualquer um pode criar um certificado autoassinado que diga algo sobre ele, assim como eu posso criar um diploma falso de Princeton que diz que eu me formei em política, física teórica e apliquei chutes e depois assinei meu próprio nome na parte inferior.
A solução [um tanto quanto desinteressante] para esse problema é escolher um conjunto de certificados autoassinados nos quais você confia explicitamente. Por exemplo, posso dizer: " Confio neste certificado autoassinado da Verisign".
Com essa confiança explícita, agora posso validar toda a cadeia de certificados. Não importa quantos certificados existam na cadeia, posso validar cada assinatura até a raiz. Quando chego à raiz, posso verificar se esse certificado raiz é aquele em que confio explicitamente. Nesse caso, posso confiar em toda a cadeia.
Confiança Conferida
A autenticação no TLS usa um sistema de confiança conferida . Se eu quiser contratar um mecânico de automóveis, talvez não confie em nenhum mecânico aleatório que encontrar. Mas talvez meu amigo ateste um mecânico em particular. Já que confio no meu amigo, posso confiar nesse mecânico.
Quando você compra um computador ou baixa um navegador, ele vem com algumas centenas de certificados raiz nos quais confia explicitamente. [4] As empresas que possuem e operam esses certificados podem conferir essa confiança a outras organizações assinando seus certificados.
Isso está longe de ser um sistema perfeito. Algumas vezes uma CA pode emitir um certificado incorretamente. Nesses casos, o certificado pode precisar ser revogado. A revogação é complicada, pois o certificado emitido sempre estará criptograficamente correto; é necessário um protocolo fora de banda para descobrir quais certificados anteriormente válidos foram revogados. Na prática, alguns desses protocolos não são muito seguros e muitos navegadores não os verificam.
Às vezes, uma autoridade de certificação inteira está comprometida. Por exemplo, se você invadir a Verisign e roubar sua chave de assinatura raiz, poderá falsificar qualquer certificado no mundo. Observe que isso não afeta apenas os clientes da Verisign: mesmo que meu certificado seja assinado por Thawte (um concorrente da Verisign), isso não importa. Meu certificado ainda pode ser falsificado usando a chave de assinatura comprometida da Verisign.
Isso não é apenas teórico. Isso já aconteceu na natureza. O DigiNotar foi famoso por ser hackeado e posteriormente faliu. O Comodo também foi hackeado , mas inexplicavelmente eles continuam no mercado até hoje.
Mesmo quando as autoridades de certificação não estão diretamente comprometidas, existem outras ameaças nesse sistema. Por exemplo, um governo usa coerção legal para obrigar uma CA a assinar um certificado falsificado. Seu empregador pode instalar seu próprio certificado CA no computador do funcionário. Nesses vários casos, o tráfego que você espera ser "seguro" é realmente completamente visível / modificável para a organização que controla esse certificado.
Algumas substituições foram sugeridas, incluindo Convergence , TACK e DANE .
Notas finais
[1] Os dados do certificado TLS são formatados de acordo com o padrão X.509 . X.509 é baseado em ASN.1 ( "Abstract Syntax Notation # 1"), o que significa que é não um formato de dados binário. Portanto, o X.509 deve ser codificado para um formato binário. DER e PEM são as duas codificações mais comuns que eu conheço.
[2] Na prática, o protocolo realmente muda para uma cifra simétrica, mas esse é um detalhe que não é relevante para sua pergunta.
[3] Presumível, a CA realmente valida quem você é antes de assinar seu certificado. Se eles não fizessem isso, eu poderia criar um certificado para google.com e solicitar que uma CA o assinasse. Com esse certificado, eu poderia intermediar qualquer conexão "segura" com o google.com. Portanto, a etapa de validação é um fator muito importante na operação de uma CA. Infelizmente, não está muito claro o quão rigoroso é esse processo de validação nas centenas de CAs em todo o mundo.
[4] Veja a lista do Mozilla de CAs confiáveis .