Desenvolvimento

28 ago, 2014

Descriptografia de Web Sites HTTPS – Parte 01: Negociação de Conexão

Publicidade

Resumo da série: Os artigos desta série irão descrever como funciona os passos do procolo utilizado pelos sites que utilizam HTTPS e como é descriptografado essa informação pelo navegador.

Objetivo: Propor ao leitor o entendimento das regras do protocolo HTTPS, a experiência prática de como ele funciona e porque ele é um protocolo seguro.

Requisitos: Os leitores devem ter conhecimentos básicos dos protocolos TCP/IP, HTTP e de como funcionam as conexões clientes (navegadores) e servidores na Web.

Composição: A série é composta de 4 artigos:

  1. Negociação de Conexão
  2. Envio do Código Secreto
  3. Cálculo de Chaves
  4. Descriptografia

Entendimento técnico dos artigos respectivamente:

  1. Handshake Protocol
  2. Utilização de Chaves Assimétricas
  3. Funcionamento do Algoritmo PRF (Pseudo Random Function)
  4. Descriptografia

Contéudo de cada artigo:

  • Analogia e entendimento da Etapa
  • Explicação técnica e algorítmica
  • Implementação

Tecnologias: Wireshark para captura de pacotes e chaves para descriptografia. O foco da implementação é o parseamento dos bytes e regra de negócios, entendendo que esses bytes da camada de aplicação já foram capturados pelo leitor/desenvolvedor por alguma biblioteca ou extensão.

Implementação: O algoritmo será implementado na linguagem PHP para o exemplo proposto.

Descriptografia de Web Sites HTTPS – Parte 01: Negociação de Conexão

Nesta série de quatro artigos iremos compreender, capturar dados e descriptografar informações dentro de uma conexão HTTPS.

Primeiramente, para estabelecermos uma conexão HTTPS utilizamos o protocolo TLS, que cuida da segurança da camada de transporte. Esse protoloco é regulamentado pela RFC 5246.

A conexão HTTPS é realizada entre Cliente e Servidor Web; essa conexão realiza algumas trocas de mensagens até o momento em que a conexão é considerada estabelecida e segura.

O primeiro objetivo é o cálculo de um código secreto (Master Secret) realizado em ambos os lados, ou seja, no cliente e no servidor. O Master Secret é alterado a cada nova conexão. Uma conexão se inicia quando o cliente solicita uma página ao servidor.

Observação: essa conexão pode ser reiniciada quando houver uma suspeita de falha de segurança.

Mensagens da Negociação

1. Inicialmente o cliente envia a mensagem ClientHello ao servidor com um código aleatório (Cliente Random) e uma lista de algoritmos em que o cliente se diz capaz de descriptografar (Cipher Suites).

1_conexao_client_random

2. O servidor responde com a mensagem ServerHello contendo outro código aleatório (Server Random) e um algoritmo escolhido da lista que o cliente disse ser capaz de descriptografar (Cipher Suite).

2_conexao_server_hello

3. O servidor envia o seu certificado na mensagem Certificate, este contém uma Chave Pública (Public Key). O navegador também analisa se o emitente do certificado é uma fonte confiável, porém não iremos verificar essa condição.

3_conexao_certificate

4. Na sequência, o servidor envia a mensagem ServerHelloDone, indicando que está esperando os dados do cliente.

4_conexao_server_hello_done

Captura

A captura de pacote desta série é demonstrada pelo software Wireshark, a versão utilizada neste artigo é 1.10.6. As classes implementadas recebem em seus métodos os pacotes capturados sempre na última camada, ou seja de aplicação.

Para a captura, foi utilizado o acesso a um site local, configurado pelo servidor Apache.

Observação: Não é necessário ter um certificado com identidade confirmada para descriptografar o HTTPS e executar o exemplo deste artigo.

Importante: Lembrando um pouco do protocolo TCP, o pacote de resposta terá que ter o valor do campo Sequence Number igual ao valor campo Acknowledgment Number correspondente ao pacote enviado. Para facilitar há teclas de atalho no Wireshark, para ir ao pacote correspondente próximo (CTRL + .) e para voltar ao anterior (CTRL + ,).

1. Ao se tratar de um protocolo HTTPS se inicia a negociação de conexão com o envio da mensagem Cliente Hello. A imagem abaixo é um print screen do Wireshark com esta mensagem:

5_wireshark_client_hello

O conteúdo do campo Random, descriminado como Cliente Random, gerou os dados no formato hexadecimal “be6fb836c97510ff31fa44a03f4411564a705837460c135feabc6005eb031438”.

2. A resposta do servidor, como já indicado anteriormente, será a mensagem ServerHello.

6_wireshark_server_hello

O conteúdo do campo Random, descriminado como Server Random, gerou os dados no formato hexadecimal “53cf9faaee53ee74d19f91c04810977224c6466dfe2d5b3d3cb2db24e14a7e33”.

O campo CipherSuite gerou os dados no formato hexadecimal “002f”, que corresponde a Cipher Suite “TLS_RSA_WITH_AES_128_CBC_SHA”, ou seja, indica que será utilizado o algoritimo para troca de chaves RSA, o algoritmo para criptografia de dados AES_128_CBC e o Hash SHA para conferencia da autenticidade da informação, este último é conhecido como MAC Key.

Implementação

Na implementação, utilizaremos a linguagem PHP, igual ou superior a versão 5.3.0. Primeiramente iremos implementar a classe e depois chamaremos os métodos implementados. Segue o código da classe SessionTLS e a atribuição dos valores obtidos para Cipher Suite, Client Random e Server Random.

class SessionTLS
{
	private $session_id;			
	private $client_random;
	private $server_random;
	private $pre_master_secret;
	private $master_secret;

	private $cipher_suite;		
	private $cipher;
	private $mac;

	private $client_write_MAC_key;		
	private $server_write_MAC_key;		
	private $client_write_key;		
	private $server_write_key;		
	private $client_write_IV;		
	private $server_write_IV;

	public function __construct()
	{
		$this->session_id = null;			
		$this->client_random = null;
		$this->server_random = null;
		$this->pre_master_secret = null;
		$this->master_secret = null;

		$this->cipher_suite = null;	
		$this->cipher = null;
		$this->mac = null;
	
		$this->client_write_MAC_key = null;		
		$this->server_write_MAC_key = null;		
		$this->client_write_key = null;		
		$this->server_write_key = null;		
		$this->client_write_IV = null;		
		$this->server_write_IV = null;		
	}
	public function setCipherSuite($cipher_suite)
	{
		$this->cipher_suite = $cipher_suite;	
	}
	public function setClientRandom($client_random)
	{
		$this->client_random = $client_random;	
	}
	public function setServerRandom($server_random)
	{
		$this->server_random = $server_random;
	}		
	public function setPreMasterSecret($pre_master_secret)
	{
		$this->pre_master_secret = $pre_master_secret;
	}	
	public function PRF($secret, $label, $seed, $size)
	{
		throw new Exception("Não implementado");
	}
	public function P_SHA256($secret, $seed, $size)
	{
		throw new Exception("Não implementado");
	}
	public function generateMasterSecret()
	{
		throw new Exception("Não implementado");
	}
	public function parserCipherMac()
	{
		throw new Exception("Não implementado");
	}
	public function getKeyMaterialBytes()
	{
		throw new Exception("Não implementado");
	}
	public function getIVSizeBytes()
	{
		throw new Exception("Não implementado");
	}
	public function getMacLengthBytes()
	{
		throw new Exception("Não implementado");
	}
	public function generateKeyBlock()
	{
		throw new Exception("Não implementado");
	}
	public function decrypt($cipherText)
	{
		throw new Exception("Não implementado");
	}
	public function decryptOpenSSL($cipher, $cipherText, $key, $IV)
	{
		throw new Exception("Não implementado");
	}
}
$TLS = new SessionTLS();
$TLS->setCipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA");
$TLS->setClientRandom(hex2bin("be6fb836c97510ff31fa44a03f4411564a705837460c135feabc6005eb031438"));
$TLS->setServerRandom(hex2bin("53cf9faaee53ee74d19f91c04810977224c6466dfe2d5b3d3cb2db24e14a7e33"));

Próximo Artigo

Após esse protocolo de troca de informações, se inicia a parte mais importante e fascinante do HTTPS, que é o envio do código secreto, no próximo artigo você entenderá como é feita essa troca de informação.

Na próxima semana, você verá na parte 02 dessa série porque o protocolo é seguro e porque mesmo quando essas informações são interceptadas elas não podem ser decifradas. Até lá.