AES e PHP: criptografia de dados.
Aplicando Advanced Encryption Standard (AES) nas interações com o BD.
Olá, como vai?
Se você lida com bancos de dados no seu dia-a-dia já deve ter percebido como os dados muitas vezes ficam expostos, de uma forma tão estruturada e fácil de serem explorados. Porém, isso nem sempre é interessante e através da criptografia podemos minimizar parte dessa exposição de dados e oferecer uma segurança maior para nossas aplicações. Vamos lá?!
CRIPTOGRAFIA
A criptografia é a técnica de alterar um texto original de acordo com algum padrão de modo que, quem não conhecer o padrão usado para criptografar, não pode saber o conteúdo do texto original. Basicamente é isso!
Dentro disso temos as criptografias simétricas e assimétricas. Ambas usam uma chave para criptografar um dado, a diferença entre elas é que:
- Simétrica: usa a mesma chave para criptografar e decriptografar
- Assimétrica: usa uma chave para criptografar e outra diferente para decriptografar.
Com isso, vamos usar o padrão AES para vermos na prática isso tudo acontecendo!
AES
O Advanced Encryption Standard (AES) — ou Padrão de Criptografia Avançada, é um dos algoritmos mais seguros e considerada uma criptografia invicta a qualquer tipo de ataque 🔒. Faz parte da criptografias simétricas, por isso para cifrar e decifrar um dado vai usar a mesma chave, e aí é que pode estar a vulnerabilidade desse padrão, mas é algo que podemos contornar.
A seguir vamos conhecer esse padrão no código, usando PHP e SQL.
AES sintaxe
Se até agora esse assunto parece complexo, a partir de agora é mais simples e você vai ver que fazer é mais fácil do que falar 😆
Para cifrar um dado usamos a função AES_ENCRYPT(). A função espera 2 parâmetros: o conteúdo a ser cifrado e a chave criptográfica que vamos usar. Exemplo:
- AES_ENCRYPT(“minha_senha_123”, “chave_secreta”);
Para decriptografar é parecido, usamos a função AES_DECRYPT(). Também espera 2 parâmetos e adivinha quais?! O conteúdo a ser decriptografado e a chave criptográfica que foi usada para cifrar. Exemplo:
- AES_DECRYPT(“?gTUA*´asEA21:º&5G<H.)F!sOP”, “chave_secreta”);
Simples, não?
Mas atenção, a chave para cifrar e decifrar são as mesmas e com isso nós temos alguns problemas corriqueiros:
- Perder a chave: se nós ciframos um dado e depois perdemos (esquecemos, etc) a chave usada, nunca será possível reverter a criptografia para o texto original. Por isso considere guardar a chave usada, futuramente você pode precisar para decriptografar!
- Vazar a chave: agora imagine que você criptografou todas as senhas usando a mesma chave. Além do problema anterior, essa chave pode ser descoberta por outra pessoa e assim esse alguém saber “o segredo” de todas as senhas. Que situação terrível! Considere gerar chaves diferentes para cada dado que for criptografar, desse jeito uma chave vazada compromete menos os seus dados e minimiza os impactos de ataques 😉.
E no PHP?
Bom, abaixo segue um exemplo simples de como pode ser gerado uma chave randomicamente e ser aplicada no comando INSERT do SQL:
Certamente vale a pena criar uma nova forma de gerar chaves criptográficas aleatoriamente. Inclusive, pode ser um dos pontos a serem estudados para praticar:
- Fazer um sistema mais secreto de geração de chaves.
- Armazenar as chaves geradas relacionada aos registros em que ela foi usada.
Tenho certeza que depois de fazer essas duas coisas você vai estar mandando super bem em AES 😜
SELECT
Eu recomendaria que, quando precisasse comparar um dado de entrada com um dado armazenado em nosso banco, eu criptografo o dado de entrada e comparo com o que tenho armazenado, não o contrário. Mas, nem tudo é comparação, às vezes realmente será necessário usar a decriptografia, então segue abaixo um exemplo de SELECT do SQL:
No exemplo acima, suponho que tenha registrado a chave criptográfica e o ID do registro do usuário em uma outra tabela do BD, chamada chaves e na busca está sendo informado o login do usuário. Com o valor de login, o comando pega a senha desse login, e busca na tabela “chaves” o valor do campo chave que foi registrado com o ID desse usuário e usa esse valor para decriptografar.
Desse forma o armazenamento de chaves em outra tabela fica perfeitamente relacionada com os registros de usuários e bem funcional. Porém, deve-se sempre considerar formas mais eficazes de fazer algo que já fazemos, por isso indico: pratique em cima disso :)
Conclusão
A implementação de uma criptografia forte em nossos sistemas não é uma coisa distante ou complexa, vimos a simplicidade para subir o nosso nível de proteção. Porém, sempre se questione e procure as formas mais inteligentes de resolver essas questões, formas que vão além desses simples exemplos apresentados!
Esses exemplos estão um pouco mais contextualizado no repositório do GitHub:
Desejo um ótimo estudo! 🚀