CSI-ES-2324/Projs/PD1
afonso 49a29e43a7
[PD2] Server done?
Co-authored-by: tsousa111 <tiagao2001@hotmail.com>
2024-05-28 20:13:33 +01:00
..
certs [PD1] Created another CA, Server and Client for testing 2024-04-19 02:20:04 +01:00
cmd [PD1] Error handling project-wide 2024-04-28 22:02:52 +01:00
internal [PD2] Server done? 2024-05-28 20:13:33 +01:00
report_content [PD1] digital envelope diagram with background 2024-04-28 22:28:32 +01:00
.gitignore Initial commit 2024-02-19 10:37:29 +00:00
.ignore [PD1] small changes 2024-04-23 11:12:18 +01:00
go.mod [PD1] Fixed almost everything 2024-04-19 23:59:26 +01:00
go.sum [PD1] Fixed almost everything 2024-04-19 23:59:26 +01:00
README.md [PD1] final 2024-04-29 00:00:06 +01:00
server.db [PD2] Server done? 2024-05-28 20:13:33 +01:00
tokefile.toml [PD1] Error handling project-wide 2024-04-28 22:02:52 +01:00

Relatório do Projeto de Desenvolvimento 1

Introdução

A comunicação eficaz dentro de uma organização é essencial para a eficiência do seu funcionamento. No entanto, num ambiente cada vez mais digital, garantir a segurança e autenticidade das comunicações tem-se vindo a tornar uma preocupação fundamental. Em resposta a esta necessidade, este primeiro projeto de desenvolvimento visa criar um serviço de mensagens seguro e autenticado.

Para contextualizar o projeto, consideremos uma organização onde informações confidenciais são frequentemente trocadas entre membros de equipas distribuídas geograficamente. Neste cenário, é crucial que as mensagens enviadas e recebidas sejam protegidas contra acessos não autorizados e manipulação por partes externas. Além disso, garantir que a identidade do remetente e a integridade da mensagem sejam verificadas é essencial para manter a confiança e a segurança das comunicações internas.

Perante estas necessidades, o projeto de desenvolvimento propõe a criação de um sistema cliente/servidor que oferece um serviço de mensagens seguro e autenticado. Através deste sistema, os membros da organização poderão trocar mensagens com garantias de autenticidade, protegendo assim a confidencialidade e integridade das comunicações.

Ao longo deste relatório iremos detalhar as decisões mais importantes tomadas no desenvolvimento do projeto, bem como as medidas de segurança implementadas para garantir a confidencialidade, integridade e autenticidade das mensagens trocadas entre os utilizadores.

Algumas notas sobre o projeto:

  • Optamos por escolher Golang como linguagem visando uma implementação mais eficiente, robusta e segura ao nível de concorrência. O modelo de concorrência baseado em goroutines e canais facilita a criação de programas concorrentes e sistemas distribuídos. Com uma sintaxe simples, semelhante a C, o Go promove a escrita de código legível e de alta qualidade. Além disso, o Go possui um ecossistema robusto de bibliotecas e ferramentas, tornando-o uma escolha adequada para o desenvolvimento de sistemas distribuídos e serviços de back-end.

  • Implementamos algumas funcionalidades extra, como o armazenamento dos dados no servidor numa base de dados sqlite3

Nas secções seguintes iremos detalhar cada componente do sistema, bem como as funcionalidades implementadas.

Análise de Risco

Esta análise de risco do sistema visa identificar as potenciais vulnerabilidades e ameaças que possam comprometer a segurança do sistema de mensagens. É essencial considerar os diversos fatores que podem impactar a integridade, confidencialidade e disponibilidade das mensagens trocadas entre os utilizadores.

Potenciais Vulnerabilidades

  1. Comunicação Não Segura - Se a comunicação entre os clientes e o servidor não foi cifrada, qualquer man in the middle consegue ler o conteúdo a ser transmitido.

  2. Armazenamento Inseguro de Chaves Privadas - Se as chaves privadas dos utilizadores forem armazenadas de forma inadequada, como em arquivos desprotegidos, existe o risco de acesso não autorizado, comprometendo a segurança e autenticidade das mensagens.

  3. Autenticação Fraca - Um sistema de autenticação vulnerável pode permitir que utilizadores mal-intencionados obtenham acesso não autorizado às contas dos utilizadores legítimos.

  4. Manipulação de Mensagens - A ausência de mecanismos eficazes de controlo pode facilitar a manipulação do conteúdo das mensagens durante a transmissão, comprometendo sua integridade.

  5. Vulnerabilidades de Software - Falhas de segurança no software desenvolvido e utilizado para implementar o sistema podem ser exploradas para obter acesso não autorizado ou comprometer a segurança dos dados.

Possíveis Ameaças:

  1. Ataques de Intercetação de Dados - Atacantes podem tentar intercetar a comunicação entre o cliente e o servidor para obter informações sensíveis, como chaves privadas ou conteúdo de mensagens.

  2. Ataques de Denial of Service (DOS) - Um ataque de DOS pode tornar o servidor inacessível ao sobrecarregá-lo com um grande volume de solicitações, prejudicando a disponibilidade do serviço.

  3. Ataques de Engenharia Social: - Atacantes podem tentar manipular os utilizadores legítimos para obter acesso às suas credenciais de acesso por meio de técnicas de engenharia social.

  4. Exploração de Vulnerabilidades de Software: - Vulnerabilidades conhecidas ou desconhecidas no software utilizado podem ser exploradas para comprometer a segurança do sistema.

Propriedades Requiridas:

  1. Autenticidade do Remetente - O cliente deseja ter a garantia de que a mensagem recebida foi realmente enviada pelo remetente indicado.

  2. Confidencialidade das Mensagens - O cliente quer assegurar que apenas ele possui a capacidade de decifrar as mensagens que lhe foram enviadas, garantindo assim a privacidade das comunicações.

  3. Servidor Malicioso - Os clientes pretendem proteger-se contra a possibilidade de o servidor agir de forma maliciosa, garantindo que as suas interações sejam seguras e protegidas, necessitando de mecanismos que garantam a segurança das suas interações independentemente da confiabilidade do servidor, como a utilização de criptografia end-to-end.

  4. Comunicação Segura com o Servidor - Os clientes exigem que a comunicação com o servidor seja segura, protegida contra acesso não autorizado e intercetação por partes não autorizadas, garantindo assim a integridade e confidencialidade dos dados transmitidos.

Medidas de Mitigação:

  1. Protocolo de comunicação - Utilizar um protocolo de comunicação que garanta a confidencialidade para proteger a comunicação entre o cliente e o servidor.

  2. Armazenamento Seguro de Chaves Privadas - Adotar práticas seguras de armazenamento para proteger as chaves privadas dos utilizadores contra acesso não autorizado, como utilizar passphrases para proteger o acesso à key store.

  3. Fortalecimento da Autenticação - Implementar métodos robustos de autenticação, como certificados digitais, para garantir a identidade dos utilizadores e proteger contra acesso não autorizado.

  4. Validação de Dados - Implementar controles de validação de dados para garantir a integridade das mensagens e prevenir a manipulação de dados por partes não autorizadas, como, por exemplo, assinar "hashes" das mensagens enviadas.

  5. Atualizações de Software - Manter o software utilizado atualizado para mitigar o risco de exploração de vulnerabilidades conhecidas e garantir a segurança do sistema.

Esta breve análise de risco destaca a importância de identificar e mitigar potenciais vulnerabilidades e ameaças para garantir a segurança do sistema desenvolvido. A implementação de medidas de segurança adequadas é essencial para proteger os dados e garantir o funcionamento seguro.

Decisões de Arquitetura e Implementação

Tendo em consideração as vulnerabilidades e ameaças identificadas na análise de risco, foram tomadas várias decisões de design e implementação para garantir a segurança e autenticidade do sistema de mensagens. As decisões tomadas visam proteger a confidencialidade, integridade e autenticidade das mensagens trocadas entre os utilizadores, bem como garantir a segurança da comunicação entre o cliente e o servidor.

  1. TLS (Transport Layer Security)

    • Cada conexão entre cliente e servidor é protegida pelo protocolo TLS, garantindo que a comunicação seja segura e privada.
    • Cliente e servidor trocam certificados para autenticar as suas identidades.
    • Ambos verificam se o certificado foi emitido pela Autoridade de Certificação (CA) central.
    • O cliente verifica se comunica com o servidor legítimo.
  2. End-to-End Encryption (E2EE)

    • Ao enviar uma mensagem, o cliente assina a hash do texto simples com a sua chave privada.
    • A assinatura é anexada ao texto limpo e esse conjunto é cifrado com uma chave de sessão gerada aleatoriamente.
    • A chave de sessão é cifrada com a chave pública do destinatário, Isso garante que apenas o destinatário possa decifrar a mensagem.
  3. Visualização da Lista de Mensagens Não Lidas

    • Quando um cliente solicita a sua lista de mensagens não lidas, apenas o assunto é enviado, não o conteúdo cifrado.
    • O cliente deve decifrar o assunto para visualizá-lo.
  4. Visualização de Mensagens

    • Quando um cliente solicita uma mensagem, é enviado o conteúdo todo da mensagem.
    • O cliente deve decifrar o assunto e o corpo da mensagem para visualizá-los.
  5. Troca de Chaves Públicas

    • Quando um cliente precisa da chave pública de outro cliente, solicita o certificado desse cliente ao servidor.
    • Verifica-se se o certificado foi emitido pela CA central e se pertence ao cliente desejado.
  6. Verificação de Inputs

    • Tanto cliente quanto servidor realizam verificações básicas nos inputs para garantir a sua integridade.
    • Ambos desconfiam um do outro e verificam cuidadosamente todos os inputs.
  7. Confiança na CA Central

    • A única confiança absoluta neste sistema é depositada na Autoridade de Certificação central, responsável por emitir os certificados.

Certificates and Keys

Para gerar os certificados e chaves necessárias para a comunicação segura entre o cliente e o servidor, foram seguidos os seguintes passos utilizando a ferramenta OpenSSL. Estes passos incluem a geração de chaves privadas, certificados e keystores para o servidor e clientes, bem como a assinatura dos certificados pela CA central.

  1. Gerar CA key e o certificate
openssl genrsa -aes256 -out CA/CA.key 4096
openssl req -x509 -new -nodes -key CA/CA.key -sha256 -days 18250 -out CA/CA.pem -subj "/2.5.4.3=CA"

A passhphrase da CA é 1234

  1. Gerar a server key e CSR
openssl genrsa -out server/server.key 4096
openssl req -new -key server/server.key -out server/server.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=SERVER"
  1. Assinar o CSR do server com a CA
openssl x509 -req -in server/server.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out server/server.crt -days 1825 -sha256
  1. Gerar o keystore do server
openssl pkcs12 -export -out server/server.p12 -inkey server/server.key -in server/server.crt -certfile CA/CA.pem -name "ServerKeyStore"

A passphrase usada para o keystore é server

  1. Gerar as chaves e CSR de cada client
openssl genrsa -out client{NUM}/client{NUM}.key 4096
openssl req -new -key client{NUM}/client{NUM}.key -out client{NUM}/client{NUM}.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=CL{NUM}/2.5.4.3=Client {NUM}"
  1. Assinar os CSR dos clientes com a CA
openssl x509 -req -in client/client.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out client/client.crt -days 1825 -sha256
  1. Gerar o keystore do client
openssl pkcs12 -export -out client{NUM}/client{NUM}.p12 -inkey client{NUM}/client{NUM}.key -in client{NUM}/client{NUM}.crt -certfile CA/CA.pem -name "Client{NUM}KeyStore"

A passphrase usada para o keystore é client{NUM}

Neste processo, foram geradas as chaves privadas, certificados e keystores necessários para estabelecer uma comunicação segura entre os clientes e o servidor. Os certificados foram assinados pela Autoridade de Certificação (CA) central, garantindo a autenticidade e integridade dos certificados emitidos. Os keystores contêm tanto o certificado quanto a chave privada do cliente ou servidor, protegidos por passhprase para garantir a confidencialidade e segurança das chaves privadas. Este processo de geração de certificados e keystores é essencial para estabelecer uma comunicação segura e autenticada entre os componentes do sistema.

Certificados

  • Autenticidade: Os certificados são assinados digitalmente pela Autoridade de Certificação (CA) central, garantindo sua autenticidade. Isso significa que os clientes podem verificar se o certificado foi emitido por uma entidade confiável.
  • Criptografia: Os certificados contêm a chave pública do cliente ou do servidor, que é usada para estabelecer uma comunicação segura por meio de criptografia assimétrica. Isso permite que as mensagens sejam cifradas pelo remetente e decifradas apenas pelo destinatário.
  • Verificação: Antes de confiar num certificado, os clientes verificam sua validade, incluindo a data de expiração e a correspondência com a entidade emissora. Isso ajuda a evitar a utilização de certificados inválidos ou falsificados.

Keystores

  • Armazenamento Seguro: Os keystores são arquivos protegidos por passphrase que contêm tanto o certificado quanto a chave privada do cliente ou servidor. Essas informações sensíveis são protegidas por meio de criptografia, garantindo que apenas o proprietário autorizado possa acessá-las.
  • Proteção da Chave Privada: A passphrase do keystore protege a chave privada contra acesso não autorizado. Isso é crucial, pois a chave privada é usada para decifrar as mensagens recebidas e assinar as mensagens enviadas, garantindo a autenticidade e integridade da comunicação.
  • Confidencialidade: Como os keystores são protegidos por passphrase, mesmo que alguém obtenha acesso ao arquivo, não poderá extrair a chave privada sem a passphrase correta. Isso ajuda a manter a confidencialidade das chaves privadas dos usuários.

Criptografia

É importante destacar que, para garantir a segurança e integridade das mensagens, implementamos um protocolo de comunicação seguro. Este protocolo utiliza tanto criptografia simétrica quanto assimétrica. As mensagens são cifradas com uma chave de sessão gerada aleatoriamente, que, é cifrada com a chave pública do destinatário para garantir a confidencialidade. As mensagens são também assinadas com a chave privada do emissor para autenticidade. Dessa forma, asseguramos que as mensagens sejam protegidas contra acessos não autorizados e que a sua origem possa ser verificada.

Digital Envelope

Networking

O canal de comunicação estabelecido entre o cliente e o servidor nesta implementação garante uma troca de dados segura e criptografada utilizando o protocolo TLS (Transport Layer Security). Ambos, cliente e servidor, empregam configurações TLS para cifrar os dados durante a transmissão, assegurando confidencialidade e integridade. Durante o handshake TLS, o servidor valida o certificado do cliente para verificar sua autenticidade, prevenindo acessos não autorizados. Este mecanismo robusto de segurança protege o canal de comunicação contra escutas, adulterações e ataques do tipo "man in the middle", garantindo uma troca de informações segura e confiável entre o cliente e o servidor.

Protocolo de Comunicação

O package protocol.go define um conjunto de estruturas e funções que representam os diferentes tipos de pacotes que podem ser transmitidos entre o cliente e o servidor. Cada tipo de pacote é representado por uma constante PacketType, que indica a natureza da informação contida no pacote através de uma flag.

As estruturas de dados definidas, como GetUserCert, GetUnreadMsgsInfo, GetMsg, SendMsg, AnswerGetUserCert, AnswerGetUnreadMsgsInfo e AnswerGetMsg, descrevem os formatos específicos de cada tipo de pacote a ser enviado e recebido. Cada estrutura contém os campos necessários para armazenar e representar os dados associados a cada tipo de pacote.

Além disso, foram implementadas funções auxiliares para criar instâncias de cada tipo de pacote, como NewGetUserCert, NewGetUnreadMsgsInfo, NewGetMsg, NewSendMsg, NewAnswerGetUserCert, NewAnswerGetUnreadMsgsInfo e NewAnswerGetMsg. Estas funções facilitam a criação de pacotes com os dados necessários de forma estruturada.

Para facilitar a serialização e desserialização dos pacotes em formato JSON, foram implementadas funções Unmarshal específicas para cada tipo de pacote. Estas funções convertem os dados do pacote entre o formato JSON e as estruturas de dados correspondentes, permitindo a comunicação eficiente entre o cliente e o servidor.

Este package serve como uma camada de abstração que facilita a comunicação entre os componentes cliente e servidor, garantindo que os dados sejam transmitidos de forma estruturada e standardized, facilitando o desenvolvimento, manutenção e expansão do sistema de comunicação.

Sqlite3 Database

Como mencionado anteriormente neste relatório, uma das funcionalidades adicionais implementadas foi o armazenamento dos dados do servidor numa base de dados persistente. Neste projeto, optamos por utilizar o SQLite3. Este é utilizado para armazenar as mensagens enviadas e recebidas pelos utilizadores, além dos certificados digitais dos clientes. A escolha de uma base de dados permite a persistência segura e eficiente dos dados, assegurando que as mensagens e certificados sejam armazenados de maneira duradoura e acessível.

Em relação à segurança contra ataques como SQL Injection, é crucial adotar medidas para mitigar esse tipo de ameaça. A utilização de prepared statements é uma prática essencial para prevenir ataques deste tipo. Com prepared statements, os valores dos parâmetros são tratados como dados e não como parte do comando SQL, o que reduz significativamente o risco de injeção de código malicioso. Essa abordagem fortalece a segurança do sistema, garantindo a integridade e confiabilidade das operações da base de dados.

Verificações e Testes de Segurança

Para realizar testes e verificações de segurança implementamos também um Fake Client, Server e CA, que permitem testar a segurança do sistema em diferentes cenários, como tentativas de intercetação de dados, manipulação de mensagens, autenticação fraca e outros tipos de ataques.