Durante o desenvolvimento do nosso Plugin para proteção de Login no WordPress, estudamos algumas ferramentas open source para entender o que estavam fazendo para anonimizar IP, um requisito da GDPR e LGPD.
O IP é tido como informação sensível pelas duas legislações e é necessário pedir consentimento do usuário antes de armazenar essa informação.
Uma alternativa para não depender do consentimento é anonimizar o IP para algumas funções. Como anonimizar, a legislação diz que não pode ser identificável o usuário final.
O IP não é uma forma direta de sabermos a pessoa que está do outro lado, mas se o usuário se identificar em algum momento do processo (digamos, ao efetuar uma compra), poderíamos associar todas as ações anteriores daquele IP (todas as pesquisas de produtos por exemplo) ao usuário agora identificado, o que seria uma violação.
Isso impacta ferramentas de Web Analytics, como o Google Analytics, mas também ferramentas de Web Firewall e de segurança em geral, pois as mesmas costumam armazenar essa informação junto aos dados de navegação.
Quando observei as ferramentas, vi que algumas que se denominavam em conformidade com a GDPR, adotavam o Hash de IP como meio de anonimizar o IP.
Uma função Hash recebe uma palavra na entrada, nesse exemplo o IP e calcula uma sequência a partir da mesma, normalmente representada em formato hexadecimal.
A primeira prerrogativa da função Hash é que, a partir do resultado obtido, não é possível se obter “facilmente” o valor de entrada, ênfase no facilmente.
No exemplo abaixo, o resultado 253 poderia ser da palavra SEGREDO ESGREDO, GREEDOS ou qualquer combinação, ou ainda outras letras não relacionadas e mesmo palavras com outros tamanhos.
A segunda prerrogativa de algorítimos de Hash é que, dada uma entrada, a saída calculada é sempre a mesma, por exemplo, o Hash SHA1 do IP 192.168.0.1 sempre será: 24682ccf0d260b650fd5891de58d141b1fe8c316, não importa quantas vezes usamos ele, conforme expliquei nesse outro artigo.
Bom, voltando ao problema original, o que vimos implementado foram ferramentas calculando o Hash do IP e armazenando em uma tabela.
Acontece que o Hash de um valor não deixa esse valor anônimo, por isso a ênfase no “facilmente” alguns parágrafos atrás.
O problema é que o espaço de numeração de IPv4 é limitado em termos computacionais, são apenas 32 bits de endereçamento, normalmente representado por 4 números, a famosa numeração 192.168.0.1 que conhecemos.
Isso nos dá cerca de 4 bilhões de IPs existentes (256^4 = 4.294.967.296 pra ser exato), parece muito, mas para calcular o Hash desses 4 bilhões de IPs, pode ser feito em algumas horas com um computador comum.
Na prática, é possível reverter um Hash armazenado para o IP original em no máximo algumas horas utilizando um ataque de dicionário (dizemos ataque de dicionário pois conhecemos previamente todas as combinações possíveis de IPs, esse é nosso “dicionário” para cálculo).
Se é reversível, não é anonimizado, então não está conforme com a GDPR
Algumas horas para reverter um IP pode ser um pouco demais, então vamos para outra forma do mesmo ataque:
Rainbow Tables
Rainbow Tables são tabelas de Hash pré-calculadas, elas servem para efetuar ataques de dicionário de forma mais rápida.
Para nosso caso, devemos calcular os Hashs de todos os IPs e deixar isso pré-calculado e armazenado.
São armazenados então com o Hash ordenado, ou seja, uma Rainbow Table dos IPs de 192.168.0.1 a 192.168.0.9 se parecerá com isso, veja que os Hashs estão em ordem alfabética:
1dcca23355272056f04fe8bf20edfce0 192.168.0.5 26ab0db90d72e28ad0ba1e22ee510510 192.168.0.2 48a24b70a0b376535542b996af517398 192.168.0.4 6d7fce9fee471194aa8b5b6e47267f03 192.168.0.3 7c5aba41f53293b712fd86d08ed5b36e 192.168.0.9 84bc3da1b3e33a18e8d5e1bdd7a18d7a 192.168.0.7 9ae0ea9e3c9c6e1b9b6252c8395efdc1 192.168.0.6 b026324c6904b2a9cb4b88d6d61c81d1 192.168.0.1 c30f7472766d25af1dc80b3ffc9a58c7 192.168.0.8
Ou seja, dado o hash 6d7fce9fee471194aa8b5b6e47267f03, rapidamente encontraríamos o IP número 192.168.0.3 que originou o mesmo.
Isso pode ser armazenado em um banco de dados com índice para busca mais rápida, ou criado um banco de dados específico (digamos, usando árvore binária) para maior performance e menor espaço de armazenamento.
Lembrando que o IP, pelo protocolo IPv4 tem apenas 32 bits e um Hash de MD5 tem apenas 128 bits, precisamos de 160 bits, ou 20 bytes para cada registro.
Considerando toda a numeração de IPv4 de 4 bilhões de endereços, precisamos de cerca de 80 Gbytes para armazenar toda a faixa. Se usarmos alguns bytes de controle e uso do índice podemos chegar a cerca de 100Gb em disco usando um SGBD comum.
Um SGBD comum faria essa consulta em alguns mili segundos, ou seja, dado um Hash de um IP que deveria ser anonimizado, é possível ser revertido em uma consulta simples e rápida.
Isso posto, não podemos considerar de forma nenhuma que o Hash de um IP é anonimizar um IP.
Se é reversível, não é anônimo e não está conforme a GDPR
Igualmente para outros documentos sensíveis, como CPF, RG, SSN (Social Security Number) Telefones, todos dentro de um intervalo conhecido e previsíveis, são sensíveis a ataques de dicionário e rainbow tables.
O CPF por exemplo, tem apenas 9 dígitos, os dois últimos são para controle e podem ser facilmente calculados, são apenas 1 bilhão de combinações possíveis, 4 vezes menos do que o IPv4.
Sendo assim, o uso de 20Gb de espaço em disco permitiria reverter o Hash de qualquer CPF em microsegundos, usando poucos IOPS, uma base com 100 mil clientes seria convertida de Hash em CPF em poucos minutos em um computador comum.
Se você precisa armazenar esses dados, considere utilizar criptografia comum com chave simétrica ou Tokenização, pelo menos ninguém irá confundir acreditando que o dado está em sigilo quando não está.
Se você precisar anonimizar esses dados, considere outros métodos como Data Blurring ou Masking.
Referências e outras leituras: