Melhores Práticas de Segurança: Criptografia simétrica com AES em Java e Android

Patrick Favre-BullePatrick Favre-Bulle
6 de Janeiro, 2018 – 11 min ler

/div>

Neste artigo irei pô-lo a par da Norma Avançada de Criptografia (AES), modos de blocos comuns, porque é que precisa de preenchimento e vectores de iniciação e como proteger os seus dados contra modificações. Finalmente, mostrar-lhe-ei como implementar isto facilmente com Java, evitando a maioria dos problemas de segurança.

O que todo o Engenheiro de Software deve saber sobre AES

AES, também conhecido pelo seu nome original Rijndael, foi seleccionado pelo NIST em 2000 para encontrar um sucessor para o Data Encryption Standard(DES) datado. AES é uma cifra de bloco, o que significa que a encriptação acontece em grupos de bits de comprimento fixo. No nosso caso, o algoritmo define blocos de 128 bits. O AES suporta comprimentos de chave de 128, 192 e 256 bit.

Todos os blocos passam por muitos ciclos de rondas de transformação. Omitirei aqui os detalhes do algoritmo, mas o leitor interessado é referido no artigo da Wikipedia sobre AES. A parte importante é que o comprimento da chave não afecta o tamanho do bloco mas o número de repetições das rondas de transformação (chave de 128 bit é 10 ciclos, chave de 256 bit é 14)

até Maio de 2009, os únicos ataques publicados com sucesso contra as AES completas foram ataques de canal lateral em algumas implementações específicas. (Fonte)

Quer codificar mais de um Bloco?

Então o AES apenas codificará 128 bit de dados, mas se quisermos codificar mensagens inteiras, precisamos de escolher um modo de bloco com o qual vários blocos podem ser codificados para um único texto cifrado. O modo de bloco mais simples é o Electronic Codebook ou BCE. Utiliza a mesma chave inalterada em cada bloco como este:

Image from Wikpedia

Isto é particularmente mau, uma vez que blocos de texto em quadrícula idênticos são encriptados com blocos de texto em quadrícula idênticos.

/div>

Image encriptado com BCE modo bloco revela padrões do original (experimente você mesmo)

p>Rembrar-se de nunca escolher este modo a não ser que apenas encripte dados inferiores a 128 bit. Infelizmente ainda é frequentemente mal utilizado porque não requer que forneça um vector inicial (mais sobre isso mais tarde) e por isso parece ser mais fácil de manusear para um programador.

Um caso tem de ser manuseado com modos de bloco: o que acontece se o último bloco não for exactamente 128 bit? É aí que o acolchoamento entra em jogo, ou seja, o preenchimento dos bits em falta do bloco. O mais simples dos quais apenas preenche os bocados em falta com zeros. Não há praticamente nenhuma implicação de segurança na escolha do acolchoamento em AES.

Cadeamento de blocos de cifra (CBC)

Então, que alternativas ao BCE existem? Para uma existe o CBC que XORs o actual bloco de texto em quadrícula com o bloco de texto em quadrícula anterior. Desta forma, cada bloco de texto criptográfico depende de todos os blocos de texto em quadrícula processados até esse ponto. Utilizando a mesma imagem que antes, o resultado seria ruído não distinguível de dados aleatórios:

Image encriptado com o modo de bloco CBC parece aleatório
p> Então e o primeiro bloco? A maneira mais fácil é usar apenas um bloco cheio de, por exemplo, zeros, mas depois cada encriptação com a mesma chave e o mesmo texto em quadrícula resultaria no mesmo texto cifrado. Também, se reutilizar a mesma chave para diferentes plaintexos, facilitaria a recuperação da chave. Uma melhor maneira é utilizar um vector de inicialização aleatória (IV). Esta é apenas uma palavra de fantasia para dados aleatórios com o tamanho aproximado de um bloco (128 bit). Pense nisto como o sal da encriptação, ou seja, um IV pode ser público, deve ser aleatório e só deve ser usado uma vez. Não se esqueça, porém, que o desconhecimento do IV só dificultará a descodificação do primeiro bloco desde o CBC XOR, o texto cifrado e não o texto plaquetário do anterior.

Ao transmitir ou persistir os dados, é comum que apenas se preveja o IV para a mensagem cifrada real. Se estiver interessado em como utilizar correctamente o AES-CBC verifique a parte 2 desta série.

Counter Mode (CTR)

Outra opção é utilizar o modo CTR. Este modo de bloco é interessante porque transforma uma cifra de bloco numa cifra de fluxo, o que significa que não é necessário estofar. Na sua forma básica, todos os blocos são numerados de 0 a n. Cada bloco será agora encriptado com a chave, o IV (também aqui chamado nonce) e o valor do contador.

Image from Wikpedia

A vantagem é, ao contrário do CBC, a encriptação pode ser feita em paralelo e todos os blocos dependem do IV e não apenas do primeiro. Uma grande advertência é que um IV nunca deve ser reutilizado com a mesma chave porque um atacante pode trivialmente calcular a chave usada a partir disso.

Posso ter a certeza de que ninguém alterou a minha mensagem?

A dura verdade: a encriptação não protege automaticamente contra a modificação de dados. Na verdade, é um ataque bastante comum. Leia aqui uma discussão mais aprofundada sobre este assunto.

Então o que podemos fazer? Adicionamos apenas o Código de Autenticação de Mensagem (MAC) à mensagem encriptada. Um MAC é semelhante a uma assinatura digital, com a diferença de que a chave de verificação e autenticação são praticamente as mesmas. Existem diferentes variações deste método, o modo que é recomendado pela maioria dos investigadores chama-se Encrypt-then-Mac. Ou seja, após encriptação é calculado um MAC sobre o texto cifrado e anexado. Normalmente utiliza-se o código de autenticação de mensagem baseado em Hash (HMAC) como tipo de MAC.

, pelo que agora começa a tornar-se complicado. Para integridade/autenticidade temos de escolher um algoritmo MAC, escolher um modo de etiqueta de encriptação, calcular o MAC e anexá-lo. Isto também é lento, uma vez que toda a mensagem deve ser processada duas vezes. O lado oposto tem de ser o mesmo mas para decifrar e verificar.

Criptação autenticada com GCM

Não seria óptimo se houvesse modos que tratassem de todas as coisas de autenticação para si? Felizmente, existe uma coisa chamada encriptação autenticada que fornece simultaneamente garantias de confidencialidade, integridade e autenticidade sobre os dados. Um dos modos de bloco mais populares que suporta isto chama-se Galois/Counter Mode ou GCM (por exemplo, também está disponível como um conjunto de cifras em TLS v1.2)

GCM é basicamente modo CTR que também calcula uma etiqueta de autenticação sequencialmente durante a encriptação. Esta etiqueta de autenticação é então normalmente anexada ao texto cifrado. O seu tamanho é uma propriedade de segurança importante, pelo que deve ter pelo menos 128 bit.

É também possível autenticar informação adicional não incluída no texto da placa. Estes dados são chamados dados associados. Porque é que isto é útil? Por exemplo, os dados encriptados têm uma meta propriedade, a data de criação, que é utilizada para verificar se o conteúdo deve ser reencriptado. Um atacante pode agora alterar trivialmente a data de criação, mas se for adicionado como dados associados, o GCM também verificará esta informação e reconhecerá a alteração.

Uma discussão acalorada: Que tamanho de chave usar?

Então a intuição diz: quanto maior, melhor – é óbvio que é mais difícil forçar um valor aleatório de 256 bit do que um valor de 128 bit. Com o nosso entendimento actual de força bruta através de todos os valores de uma palavra longa de 128 bit exigiria uma quantidade astronómica de energia, não realista para ninguém em tempo sensato (olhando para si, NSA). Assim, a decisão é basicamente entre infinito e infinito vezes 2¹²⁸.

AES tem na realidade três tamanhos chave distintos porque foi escolhido como Apto Federal de Algoritmos dos EUA para ser utilizado em várias áreas sob o controlo do governo federal dos EUA . (…) Assim, os bons cérebros militares surgiram com a ideia de que deveria haver três “níveis de segurança”, para que os segredos mais importantes fossem codificados com os métodos pesados que mereciam, mas os dados de menor valor táctico poderiam ser codificados com algoritmos mais práticos, se mais fracos. (…) Assim, o NIST decidiu seguir formalmente os regulamentos (pedir três tamanhos de chave) mas também fazer a coisa inteligente (o nível mais baixo tinha de ser inquebrável com tecnologia previsível)(Fonte)

O argumento segue-se: uma mensagem encriptada AES provavelmente não será quebrada pela força bruta da chave, mas por outros ataques menos dispendiosos (não conhecidos actualmente). Estes ataques serão tão prejudiciais ao modo de chave de 128 bits como ao modo de chave de 256 bits, pelo que escolher um tamanho de chave maior não ajuda neste caso.

Por isso, basicamente, a chave de 128 bits é segurança suficiente para a maioria dos casos de utilização, com a excepção da protecção quântica do computador. Também a utilização de chaves encriptadas de 128 bits mais rápida do que 256 bits e o calendário de chaves para chaves de 128 bits parece estar mais bem protegido contra ataques de chaves relacionadas (no entanto, isto é irrelevante para a maioria dos usos no mundo real).

Como nota lateral: Ataques de canais laterais

Ataques de canais laterais são ataques que visam explorar questões específicas de determinadas implementações. Os próprios esquemas de cifra de encriptação não podem ser intrinsecamente protegidos contra eles. Implementações simples de AES podem ser propensas a ataques temporais e de cache entre outros.

Como exemplo muito básico: um algoritmo simples que é propenso a ataques temporais é um método equals() que compara duas matrizes de bytes secretas. Se o equals() tem um retorno rápido, ou seja, após o primeiro par de bytes que não coincidem, um atacante pode medir o tempo que leva para o equals() completar e pode adivinhar byte por byte até que todos coincidam.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *