在PostgreSQL上匿名化数据

时间:2019-07-22 23:45:01

标签: postgresql

我有一些带有一些PI列的表,我需要将它们匿名化。问题是:在其他表之间的JOIN上使用了一些列-所以我不能只使用crypt(column, gen_salt('md5')),因为在table_a和table_b的字符串awesome@email.com之间得到了不同的值。

我尝试使用MD5(列),但是很but脚:找出原始值是超级简单。

匿名处理数据并使表之间的相同字符串保持相同值的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

请注意,此处MD5可能已足够。 MD5和SHA1的问题在于它们很容易受到collision attacks的攻击。这些与诸如密码散列之类的事情有关,在这种情况下,攻击者试图制作与给定散列匹配的输入。这与这里无关。

值得关注的是,攻击者将能够从校验和中找到原始值。由于校验和会丢失信息,因此这是不可能的。无限的一组值将与校验和匹配。

重要的是,可以通过执行相同的校验和在数据库中搜索已知值。我们将使用peppering解决此问题。见下文。

也就是说,我至少使用SHA-1或SHA-2,以防万一。皮带和吊带是很好的安全保护。


这是两个选择。使用更强的校验和,或使用真实值作为种子来生成伪随机伪值。

pgcrypto模块为digest提供了strong checksum algorithms功能。随便你吧。我将使用SHA1,因为它在这种情况下是安全的,并且会生成不长的东西。

create extension pgcrypto;
select encode(digest('awesome@email.com', 'sha1'), 'hex');

请注意,具有已知电子邮件地址的攻击者仍可以通过执行相同的校验和在数据库中查找它。为了解决这个问题,我们向每个值添加一个pepper。只要每次都相同,就只是一些随机垃圾。

select encode(digest('awesome@email.com' || 'g4l4Q63tmpKC1w', 'sha1'), 'hex');

一旦转换了数据库,就不再需要Pepper。销毁它以防止任何人同时访问经过清理的数据和胡椒。


问题是a8fefdbe42a0e3685647e72b86e34da717e6a400不再是电子邮件地址。这可能会导致实际使用数据时出现问题。

我们可以提出一些看起来更合理的东西。

select
  encode(digest(email[1] || 'g4l4Q63tmpKC1w', 'sha1'), 'hex') ||
  '@' ||
  encode(digest(email[2] || 'g4l4Q63tmpKC1w', 'sha1'), 'hex')
from (
  select string_to_array('awesome@email.com', '@') email
) as emails;

73372a7dc80bdbc3adf77382bc019322b2b30c6a@4087394c113f1ad7ba17e4bf44c6902188e20703更好,您可以根据需要对其进行优化。


另一个选择是使用一个函数,该函数使用随机数生成假的,合理的值。使用真实值的校验和加胡椒粉作为随机发生器的种子,以确保您对相同的真实输入获得相同的假值。

以下是使用Ruby出色的faker gem制作可重复的伪造电子邮件的示例。和以前一样,我们在输入内容时加了字,以使攻击者无法通过重复该过程来搜索电子邮件地址。

require 'digest'
require 'faker'

pepper = "g4l4Q63tmpKC1w"  # any random string will do

# Generate a seed from the checksum of the real value plus a pepper
seed = Digest::SHA1.new.hexdigest("foo@bar.com" + pepper).to_i(16)

# Seed Faker and generate a fake value
Faker::Config.random = Random.new(seed)
puts Faker::Internet.email # "sudie@bayernitzsche.net" 

# Re-seed Faker to demonstrate repeatability
Faker::Config.random = Random.new(seed)
puts Faker::Internet.email # "sudie@bayernitzsche.net" 

由于重复生成这些文件可能会变得昂贵,因此可以使用an LRU cache来缓存它们而不会耗尽内存。我不建议将缓存存储在磁盘上,这可能是可恢复的。


也就是说,在非生产环境中保护PII是一个很深的话题,而我只是一个安全涉猎者。我建议您研究用于掩盖数据的专业安全准则。