在 Web 应用程序中记录一些数据时,我想确保我可以识别来自不同时间但来自相同 IP 地址的数据。另一方面,由于数据将公开发布,因此出于隐私问题,我想确保无法检索实际 IP。所以我需要某种方式将 IP 地址映射到其他一些字符串,以确保 1-1 映射。
如果我理解正确,那么 MD5、SHA1 或 SHA256 可能是一个解决方案。我想知道它们在所需的处理方面是否不太昂贵?
我会对任何解决方案感兴趣,但如果在 Perl 中有实现会更好。
在 Web 应用程序中记录一些数据时,我想确保我可以识别来自不同时间但来自相同 IP 地址的数据。另一方面,由于数据将公开发布,因此出于隐私问题,我想确保无法检索实际 IP。所以我需要某种方式将 IP 地址映射到其他一些字符串,以确保 1-1 映射。
如果我理解正确,那么 MD5、SHA1 或 SHA256 可能是一个解决方案。我想知道它们在所需的处理方面是否不太昂贵?
我会对任何解决方案感兴趣,但如果在 Perl 中有实现会更好。
我认为MD5会足够好而且足够快。您需要添加一些恒定的盐字符以避免彩虹表/网络查找。例如,字符串“127.0.0.1”有 md5 f528764d624db129b32c21fbca0cb8d6,它有很多谷歌点击。另一方面,“szabgab127.0.0.1”得到“您的搜索 - 501ff2fbdca6ee72247f8c61851f17b9 - 不匹配任何文档”(直到我发布这个答案......)
使用拉宾指纹。它快速且易于实施。
给定一条 n 位消息 m 0 ,...,m n-1,我们将其视为有限域 GF(2) 上的 n-1 次多项式。
然后我们在 GF(2) 上选择一个 k 次随机不可约多项式 p(x),我们将 m 的指纹定义为 f(x) 除以 p(x) 在 GF( 2) 可以看作是 k-1 次的多项式或 k 位数。
请注意,这仍然不是您寻求的完美哈希函数,但要获得一个,您可能会面临破解该函数并从哈希中获取原始 IP 的问题。在大多数情况下,指纹识别中极低的碰撞几率是可以接受的。
另请注意,无论您最终使用什么哈希函数,如果您的哈希函数已知,查找哪些日志条目来自给定 IP 地址将是微不足道的。如果你想保护自己免受这种情况的影响,你应该加密散列。
If you just use hashes, then someone can do a brute force attack.
The easiest thing to do is to use a Bloom Filter. In particular, the C++ Bloom filter implementation at http://www.afflib.org/ allows you to add arbitrary strings to the Bloom filter and then probe to see if they are present or not. If you want to protect against a brute force attack just raise your false positive frequency so it is 1 in a billion. Then you'll have uniqueness but people won't be able to figure out which IP addresses you have seen.
基于@marcog 和@daxim 的答案,您可以在日志生成设备上使用带有硬编码密钥的HMAC,例如HMAC-SHA 。如果这个秘密泄露出去,那么这个方案就会变得和目前这里给出的任何一个方案一样弱。
或者,也许更简单,您可以使用相同的密钥概念来加密 IP 地址。AES 的 128 位块大小非常适合确保所有可能的 IP 地址的 1-1 映射。只需在 ECB 模式下使用 AES。
⚠ 不要再使用MD5或SHA-1。⚠ 查看文章了解他们的弱点。
改用 salted SHA-2,Crypt::SaltedHash提供了一个很好的抽象。推荐的 Perl 绑定是Digest::SHA并使用 XS。
你说贵。你有没有分析过代码?代码还没写?那么现在考虑优化还为时过早。安全必须是首要考虑。
编辑:示例代码
use Crypt::SaltedHash;
my $normalised_string_representation_of_internet_address = '::1'; # or perhaps '10.10.10.10'
# when you first get an address, make a hash and store it
my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-512', salt_len => 32);
$csh->add($normalised_string_representation_of_internet_address);
my $salted = $csh->generate;
# later retrieve the hash and see whether it matches
my $valid = Crypt::SaltedHash->validate($salted, $normalised_string_representation_of_internet_address, 32);
另一种选择是Crypt::Eksblowfish::Bcrypt。然而,它“更好”的原因恰恰是因为它是(eks)昂贵的——可调的成本有多高——这使得破解尝试从某种程度上到荒谬的不切实际。对于您的应用程序,您可以缓存加密的 IP,这样至少在看到重复项时它不会很慢。