Diferentes formas de anonimizar dados (e hash não é uma delas)
Anonimizar dados é essencial para proteger a privacidade, mas será que você está fazendo isso da forma correta? Muita gente acredita que gerar um simples hash, como transformar o nome rafael
em 9135d8523ad3da99d8a4eb83afac13d1
, já resolve o problema, mas ele não acaba aí.
Neste artigo eu vou te mostrar por que um hash sozinho não é suficiente para anonimizar dados, e quais cuidados você deve ter quando estiver trabalhando com a anonimização. É o tipo de conhecimento que só de entender a base, você já irá se diferenciar de muita gente, mesmo que o assunto seja muito mais profundo.
Gerar um hash torna o dado anônimo?
Essa foi a pergunta que o Edward Felten respondeu em 2012, no blog do FTC, quando estava no cargo de Chief Technologist.
Um hash é uma função matemática: você dá a ele um valor de entrada e a função emite um valor de saída; e a mesma entrada sempre produz a mesma saída. O que torna um hash especial é que ele é tão imprevisível quanto uma função matemática pode ser — ele é projetado para que não haja rima ou razão para seu comportamento, exceto pela regra de que a mesma entrada sempre produz a mesma saída.
Como exemplo, vamos considerar "anonimizar" um SSN (algo como nosso CPF, porém secreto) utilizando o SHA-1. Essa função retornará uma string similar à b0254c86634ff9d0800561732049ce09a2d003e1
. Um SSN é composto por 9 números, então é bem diferente do resultado do SHA-1.
Apesar disso, é bem fácil descobrir qual é o SSN criptografado com uma função como o SHA-1. O analista simplesmente adivinha o SSN por força bruta: ele enumera todos os possíveis SSNs e faz o hash de cada um. Depois, pode comparar a string acima com a tabela de SSNs que ele gerou.
Nos comentários, o Edward Felten dá como alternativa usar um "salt longo e secreto" para o hash, e isso é abordado nos outros artigos que mencionarei.
Como anonimizar dados corretamente, se o hash não é o suficiente?
O texto anterior possivelmente te deixou com esta dúvida, e coincidentemente é exatamente uma pergunta feita no Security Stack Exchange. A resposta mais votada nos dá duas alternativas para a anonimização:
- Usar tokenização. Isso significa que você cria um banco de dados separado com IDs gerados aleatoriamente mapeando para o valor desejado. Você então insere o token em vez da identidade real.
- Se você não precisa mapear os dados de volta, pode usar, por exemplo, um HMAC com um segredo longo gerado aleatoriamente. Sem o segredo, você não pode utilizar força bruta para adivinhar os IDs originais, mesmo quando eles consistam em apenas 1 único caractere.
Usar um HMAC é, na verdade, a maneira correta de usar um "salt secreto" (um salt nunca é considerado secreto na criptografia). Ou seja, é o que Edward Felten mencionou no blog do FTC.
Essas são as respostas curtas, mas ainda assim, anonimizar dados não é algo tão simples, e mesmo seguindo essas recomendações, você pode não estar fazendo o suficiente. O próximo link é um mergulho profundo no assunto.
O falso fascínio do hash para anonimização
Este é o título do artigo publicado no blog da Teleport (uma empresa que não conheço, mas o artigo é bom).
Ao longo do artigo, vamos usar a seguinte tabela como "base de dados". Considere que são registros de login.
Timestamp | IP | Usuário |
---|---|---|
2018-04-15 13:01 | 1.2.3.4 | 45d9908cf9f290f7097bf8152c288055275ebe93f2dc3781c8a1c60a43cd6ae5 |
2018-04-05 08:05 | 5.6.7.8 | e9e326d5f3b4741fe5967b5f9f3997e6275331ba18567ef9ef9e0e3a00e78371 |
2018-04-16 12:27 | 9.1.2.3 | 4135aa9dc1b842a653dea846903ddb95bfb8c5a10c504a7fa16e10bc31d1fdf0 |
A tabela acima utiliza o SHA256 para criptografar o nome do usuário. Apesar de parecer anônimo e difícil de adivinhar na força bruta, caso você esteja procurando por um usuário específico, como knisbet
, fica fácil descobrir se ele está na base de dados ou não.
É um caso parecido com o SSN mencionado no blog do FTC, mas aqui já sabemos de antemão o que estamos procurando (informações sobre um usuário específico), precisando apenas gerar o hash para o nome de usuário desejado e verificar se ele está na base de dados.
Tornar o hash mais lento, ao usar bcrypt, por exemplo, também não resolve esse problema, porque o dado que queremos descobrir é uma string pública e fácil de adivinhar, como o nome de usuário ou um endereço de e-mail. Para senhas, isso serve porque é uma string difícil de adivinhar.
Mas já sabemos resolver o problema do hash, certo?
Suponha que o problema do hash tenha sido resolvido e estamos usando id
s aleatórios, como a resposta do Security Stack Exchange mencionou, ou HMACs. Ainda assim, temos outros problemas.
Imagine que um usuário declarou em alguma rede social, como o X, ou num site de status, que ocorreu um problema no sistema e ele precisou acessar no dia 15/04/2018, por volta das 13hrs, para resolver o problema. Se não houver muitos outros registros nesse momento, é fácil ver que é o primeiro usuário neste banco de dados.
E se você estava conversando com outra pessoa, que entrou de férias no dia 5 de abril, também consegue identificá-la, porque o último acesso foi no dia 5, e você só precisa identificar algum registro que atenda este requisito.
Caso outro conjunto de dados tenha sido comprometido, e nele é possível ver que o usuário alex
utilizou o IP 9.1.2.3 no dia 12 de abril, também será possível identificá-lo na tabela acima.
Combinar dados anonimizados que podem ser correlacionados a outras partes dos seus dados que não são anonimizadas, em muitos casos torna trivial desmascarar usuários em conjuntos de dados anonimizados. Normalmente, você só precisa de alguns pontos de dados com precisão relativamente baixa para desmascarar um grande conjunto de dados.
Então, como anonimizar os dados?
No artigo, o autor diz que a forma de anonimizar depende inteiramente do conjunto de dados e de como ele deve ser usado.
Na Teleport, a maneira que escolheram anonimizar os dados é gerando HMACs com um segredo que é relevante apenas para o cluster Teleport. Isso significa que o algoritmo usado para calcular knisbet
-> 45d99...
depende de uma chave secreta e imprevisível que vive na rede dos clientes, e que a empresa não tem acesso à essa chave. Cada cluster também usa sua própria chave, então se houver um vazamento nos segredos, isso limita o potencial desmascaramento a apenas um único cliente.
E o mais importante, a empresa coleta apenas dados suficientes para cumprir o propósito declarado. Quanto menos pontos de dados são coletados, menor a oportunidade de alguém correlacionar os dados.
Há várias maneiras de melhorar isso, sendo algumas:
- Fazer com que os clusters rotacionem seus segredos todo mês, para que os dados coletados não possam ser correlacionados mês a mês.
- Armazenar apenas hashes parciais, o que tornaria um ataque de força bruta mais difícil.
Uma outra alternativa
Como mencionado na resposta do Security Stack Exchange, uma alternativa é, em vez de anonimizar os dados que você deseja proteger por meio de um algoritmo, gerar uma tabela de consulta de números de ID ou UUIDs para substituir o texto. Então knisbet
= 1
, alex
= 2
, etc. e armazenar isso em um banco de dados em um domínio de segurança separado com controles de acesso separados.
Dessa forma, você sempre tem que consultar a tabela de referência e fazer uma troca de dados reais por dados anonimizados. Isso tem a vantagem de não poder ser quebrado pelo próprio algoritmo, mas ainda tem a fraqueza de que se essa tabela for comprometida ou incluir informações que podem ser correlacionadas, o conjunto de dados pode ser trivialmente desmascarado.
Não é tão simples, mas melhorar não é tão complicado
Como vimos, usar um hash não é suficiente. Esse seria apenas o “primeiro passo”. Um HMAC já é algo melhor, mas a verdadeira proteção de dados exige uma abordagem mais completa, que leva em consideração as relações entre os dados e a possibilidade de outros vazamentos dentro do sistema. A chave aqui é entender que anonimizar dados não se trata apenas de aplicar uma função matemática, mas sim de garantir que as informações que você está protegendo não possam ser facilmente correlacionadas e desmascaradas.
Um dos grandes insights que eu tive lendo os artigos foi sobre o uso de HMAC com uma chave secreta exclusiva para cada cliente, permitindo que o processo de anonimização ocorra sem que seu sistema precise conhecer a chave, além da sugestão de rotacionar o segredo, minimizando os danos em caso de vazamentos. A análise de correlação entre os dados também foi um ponto bem relevante.
Anonimizar dados corretamente não é simples, mas sair do zero é fácil. Pense de forma estratégica sobre como proteger as informações sensíveis, antecipando possíveis pontos de falha. Esse conhecimento é um diferencial que pode não só melhorar a segurança dos seus dados, mas também destacar você como profissional. Não é comum encontrar profissionais com essa preocupação por aí, ainda mais num momento onde tantos desenvolvedores “são formados em seis meses”.