Num mundo cada vez mais orientado por dados, a gestão segura das informações dos utilizadores tornou-se mais crucial do que nunca.
Como desenvolvedores, já enfrentamos desafios consideráveis, como lidar com sistemas complexos e frágeis, com múltiplos pontos de falha, enquanto transformamos desejos humanos em interfaces e back-ends funcionais. A isto, junta-se uma consideração emergente e essencial: a segurança de dados. E com razão: nós, enquanto clientes, ficamos indignados quando os nossos dados são mal utilizados (portanto, é justo oferecermos uma experiência segura e satisfatória aos nossos utilizadores), e governos e empresas exigem-no por questões de conformidade.
A Segurança de Dados como Responsabilidade Compartilhada
A complexidade da segurança reside no facto de ter várias camadas e, ao tornar-se responsabilidade de todos, acaba por não ser de ninguém. Numa equipa moderna de desenvolvimento, várias equipas controlam diretamente o fluxo de dados: desenvolvedores, administradores de bases de dados, administradores de sistema (ou pessoal de DevOps), utilizadores de back-office com privilégios, entre outros. É fácil que estas funções/equipas ignorem o problema e considerem a segurança de dados como responsabilidade de outros. No entanto, a realidade é que cada um tem as suas próprias áreas de preocupação. Um administrador de bases de dados não pode controlar a segurança ao nível da aplicação e um profissional de DevOps tem pouco controlo sobre o acesso administrativo, por exemplo.
O Papel dos Desenvolvedores na Segurança de Dados
Dito isto, os desenvolvedores detêm o maior controlo sobre os dados: constroem todas as partes da aplicação, conectam-se a diversos serviços de back-end, gerem tokens de acesso e têm acesso total às bases de dados. As aplicações que desenvolvem têm acesso irrestrito a todas as partes do sistema (por exemplo, uma aplicação Django em produção tem privilégios para descarregar ou eliminar toda a coleção S3 de uma década). Como resultado, a maior probabilidade de negligência ou falta de cuidado em termos de segurança reside no nível do código-fonte, e esta é uma responsabilidade direta do desenvolvedor.
A segurança de dados é um tema vasto e não é possível abordá-lo em profundidade num único artigo. No entanto, pretendo cobrir a terminologia essencial que os desenvolvedores devem conhecer para garantir a segurança das suas aplicações. Considere isto como um curso básico de Segurança de Dados para Aplicações.
Vamos começar!
Hash
Se pretende uma definição rigorosa, pode consultar a Wikipédia, mas, em termos simples, hash é o processo de conversão de dados para um formato ilegível. Por exemplo, usando o conhecido (e muito inseguro) processo de Codificação Base64, a frase “O meu segredo está seguro contigo?” pode ser transformada (“hashed”) em “TUl1IHNlZ3JlZG8gZXN0w6Egc2VndXJvIGNvbnRpZ28/”. Se começar a escrever o seu diário pessoal em Base64, a sua família não conseguirá ler os seus segredos (a menos que saibam como descodificar Base64)!
Esta ideia de “embaralhar” dados é usada para armazenar senhas, números de cartões de crédito, etc., em aplicações web (e deveria ser utilizada em todos os tipos de aplicações). A ideia, claro, é que em caso de fuga de dados, o atacante não possa usar as senhas ou números de cartão para causar danos reais. Algoritmos altamente robustos e sofisticados são usados para executar este hash. Algo como Base64 seria uma piada e seria facilmente quebrado por qualquer atacante.
O hash de senhas usa uma técnica criptográfica conhecida como hash unidirecional, o que significa que, embora seja possível embaralhar os dados, não é possível decifrá-los. Então, como é que a aplicação sabe que é a sua senha quando se autentica? Bem, ela usa o mesmo processo e compara a forma codificada da sua senha com a forma codificada armazenada na base de dados. Se forem iguais, a autenticação é bem-sucedida!
Ainda sobre hashes, eis algo interessante. Se já descarregou software ou ficheiros da internet, pode ter sido instruído a verificar os ficheiros antes de os usar. Por exemplo, se pretende descarregar a ISO do Ubuntu Linux, a página de descarga mostra uma opção para verificar a sua descarga. Ao clicar nela, uma janela pop-up é exibida:
A janela indica para executar um comando que irá fazer o hash de todo o ficheiro que descarregou e comparar o resultado com a string de hash que vê na página: 5fdebc435ded46ae99136ca875afc6f05bde217be7dd018e1841924f71db46b5. Esta conversão é realizada usando o Algoritmo SHA256, cuja menção pode ser vista no final do comando: shasum -a 256 –check.
A ideia é que, se o hash produzido pela sua verificação for diferente, significa que alguém adulterou a sua descarga e lhe forneceu um ficheiro comprometido.
Alguns nomes conhecidos no domínio do hash de senhas são MD5 (inseguro e agora obsoleto), SHA-1 e SHA-2 (famílias de algoritmos, dos quais o SHA-256 é um membro, assim como o SHA-512), SCRYPT, BCRYPT, etc.
Salt
Todos os tipos de segurança são um jogo de gato e rato: o ladrão aprende o sistema atual e cria uma nova brecha, que é detetada e os fabricantes de fechaduras aprimoram a sua defesa, e assim por diante. A criptografia não é exceção. Embora a reversão de hashes para senhas se tenha tornado impossível, os atacantes desenvolveram técnicas sofisticadas que combinam adivinhação inteligente com um poder computacional elevado. Como resultado, em muitos casos, eles conseguem prever a senha correta, considerando apenas o hash.
“Sr. Rumpelstiltskin, presumo?!”
Como resultado, a técnica de salt foi desenvolvida. Isso significa que o cálculo de hash de uma senha (ou qualquer dado) é feito com base numa combinação de duas coisas: os próprios dados e uma nova string aleatória que o atacante não consegue adivinhar. Portanto, com salt, se quisermos fazer o hash da senha superman009, primeiro selecionamos uma string aleatória como “salt”, por exemplo, bCQC6Z2LlbAsqj77 e, em seguida, executamos o cálculo de hash em superman009-bCQC6Z2LlbAsqj77. O hash resultante é diferente das estruturas habituais produzidas pelo algoritmo, reduzindo consideravelmente a possibilidade de engenharia reversa inteligente ou adivinhação.
Tanto o Hash como o Salt são domínios complexos e em constante evolução. Portanto, como desenvolvedores de aplicações, nunca lidaremos diretamente com eles, mas é útil conhecê-los para tomar melhores decisões. Por exemplo, se usa um framework PHP antigo e percebe que ele usa hashes MD5 para senhas, sabe que é hora de usar outra biblioteca de senhas no processo de criação de contas de utilizadores.
Chaves
O termo “chaves” é frequentemente encontrado no contexto da criptografia. Até agora, abordamos o hash de senhas ou a criptografia unidirecional, onde convertemos os dados de forma irreversível e destruímos a sua forma original. Esta abordagem é inadequada para uso prático diário – um documento escrito e enviado por e-mail com tamanha segurança que nunca poderá ser lido não serve para nada! Assim, queremos encriptar os dados de forma que as informações possam ser abertas tanto pelo remetente como pelo destinatário, mas enquanto são transferidas ou armazenadas, devem ser ilegíveis.
Para isso, existe o conceito de “chave” na criptografia. É exatamente o que parece: a chave de uma fechadura. A pessoa que possui a informação “embaralha-a” usando um segredo chamado chave. A menos que o recetor/atacante tenha essa chave, é impossível decifrar os dados, por mais sofisticados que sejam os seus algoritmos.
Rotação de Chaves
Embora as chaves tornem a criptografia possível e fiável, elas têm os mesmos riscos que as senhas: quando alguém conhece a chave, tudo acaba. Imagine um cenário em que alguém invade parte de um serviço como o GitHub (mesmo que por alguns segundos) e consegue obter algum código de há 20 anos. Dentro do código, encontram também as chaves criptográficas usadas para criptografar os dados da empresa (uma prática horrível para armazenar chaves junto com o código-fonte, mas é surpreendente a frequência com que isso acontece!). Se a empresa não teve o cuidado de alterar as suas chaves (tal como as senhas), a mesma chave pode ser usada para causar estragos.
Como resultado, a prática de alterar as chaves com frequência evoluiu. Isso chama-se rotação de chaves e, se estiver a usar qualquer fornecedor de PaaS na nuvem respeitável, isso deve estar disponível como um serviço automatizado.
Crédito da imagem: AWS
Por exemplo, a AWS tem um serviço dedicado para isso chamado Serviço de Gerenciamento de Chaves da AWS (KMS). Um serviço automatizado evita a necessidade de alterar e distribuir chaves entre todos os servidores e é uma opção essencial quando se trata de grandes implementações.
Criptografia de Chave Pública
Se toda a conversa sobre criptografia e chaves parece complicada, tem toda a razão. Manter as chaves seguras e partilhá-las de forma que apenas o destinatário possa ver os dados gera problemas logísticos que não permitiriam que as comunicações seguras de hoje prosperassem. Mas graças à criptografia de chave pública, podemos comunicar com segurança ou fazer compras online.
Este tipo de criptografia foi um grande avanço matemático e é a única razão pela qual a Internet não se desintegra por medo e desconfiança. Os detalhes do algoritmo são complexos e altamente matemáticos, por isso só posso explicá-los conceptualmente.
Crédito da imagem: The Electronic Frontier Foundation
A criptografia de chave pública depende do uso de duas chaves para processar informações. Uma das chaves é chamada de Chave Privada e deve permanecer privada e nunca ser partilhada com ninguém. A outra é chamada de Chave Pública (daí o nome do método) e deve ser publicada publicamente. Se estiver a enviar dados para si, primeiro preciso de obter a sua chave pública, encriptar os dados e enviá-los para si. Do seu lado, pode desencriptar os dados usando a sua combinação de chave privada e chave pública. Desde que não revele acidentalmente a sua chave privada, posso enviar dados encriptados para si que só você pode abrir.
A beleza do sistema é que eu não preciso de conhecer a sua chave privada, e qualquer pessoa que intercete a mensagem não pode fazer nada para a ler, mesmo que tenha a sua chave pública. Se se está a perguntar como é possível, a resposta mais curta e não técnica vem das propriedades da multiplicação de números primos:
É difícil para os computadores fatorar números primos grandes. Portanto, se a chave original for muito grande, pode ter certeza de que a mensagem não poderá ser descriptografada mesmo em milhares de anos.
Segurança da Camada de Transporte (TLS)
Agora sabe como funciona a criptografia de chave pública. Este mecanismo (conhecer a chave pública do destinatário e enviar dados encriptados usando essa chave) é o que está por trás de toda a popularidade do HTTPS e é o que faz com que o Chrome diga: “Este site é seguro”. O que está a acontecer é que o servidor e o navegador estão a encriptar o tráfego HTTP (lembre-se, as páginas web são sequências de texto muito longas que os navegadores podem interpretar) com as chaves públicas um do outro, resultando em HTTP seguro (HTTPS).
Crédito da imagem: Mozilla. É interessante notar que a criptografia não acontece na Camada de Transporte como tal. O modelo OSI não diz nada sobre a criptografia de dados. Os dados são encriptados pela aplicação (neste caso, o navegador) antes de serem transferidos para a Camada de Transporte, que posteriormente os envia para o destino, onde são desencriptados. No entanto, o processo envolve a Camada de Transporte e, no final, resulta no transporte seguro de dados, pelo que o termo genérico “segurança da camada de transporte” se tornou comum.
Pode encontrar o termo Secure Socket Layer (SSL) em alguns casos. É o mesmo conceito que o TLS, exceto que o SSL surgiu muito antes e foi agora substituído pelo TLS.
Criptografia de Disco Completo
Por vezes, as necessidades de segurança são tão intensas que nada pode ser deixado ao acaso. Por exemplo, servidores de governo onde todos os dados biométricos de um país são armazenados não podem ser provisionados e executados como servidores de aplicações normais, pois o risco é muito elevado. Não é suficiente que os dados sejam encriptados apenas no momento da transferência. Eles também devem ser encriptados quando estão em repouso. Para isso, a criptografia de disco completo é usada para encriptar a totalidade de um disco rígido para garantir que os dados estão seguros mesmo que ocorra uma invasão física.
É importante notar que a criptografia de disco completo deve ser feita ao nível do hardware. Isto porque, se encriptarmos o disco inteiro, o sistema operativo também é encriptado e não pode ser executado quando a máquina é iniciada. Portanto, o hardware precisa de entender que o conteúdo do disco está encriptado e deve efetuar a desencriptação em tempo real, à medida que envia os blocos de disco solicitados para o sistema operativo. Devido a esse trabalho extra, a criptografia de disco completo resulta em leituras/escritas mais lentas, o que deve ser tido em conta pelos desenvolvedores de tais sistemas.
Criptografia de Ponta a Ponta
Com os constantes pesadelos de privacidade e segurança das grandes redes sociais hoje em dia, o termo “criptografia de ponta a ponta” tornou-se comum, mesmo para quem não cria ou mantém aplicações.
Vimos anteriormente que a criptografia de disco completo oferece a melhor estratégia à prova de balas, mas para o utilizador comum não é conveniente. Imagine que o Facebook quer que os dados do telefone que ele gera e armazena no seu telefone sejam seguros, mas não pode aceder ao seu telemóvel para encriptá-lo e bloquear todo o resto.
Por este motivo, estas empresas iniciaram a criptografia de ponta a ponta, o que significa que os dados são encriptados quando são criados, armazenados ou transferidos pela aplicação. Ou seja, mesmo quando os dados chegam ao destinatário, permanecem totalmente encriptados e apenas acessíveis pelo telefone do destinatário.
Crédito da imagem: Google
Note que a criptografia de ponta a ponta (E2E) não oferece nenhuma garantia matemática como a criptografia de chave pública. É apenas uma encriptação padrão em que a chave é armazenada com a empresa e as suas mensagens são tão seguras quanto a empresa decidir.
Conclusão 👩🏫
Provavelmente já ouviu falar da maioria destes termos. Talvez até todos eles. Nesse caso, encorajo-o a rever o seu entendimento destes conceitos, bem como a avaliar a seriedade com que os aborda. Lembre-se que a segurança de dados em aplicações é uma luta que tem de vencer sempre (e não apenas uma vez), pois basta uma única violação para destruir setores, carreiras e até vidas inteiras!