在Web应用程序中记录某些数据时,我想确保能够识别出来的时间不同但来自同一IP地址的数据。另一方面,出于隐私问题,因为数据将公开发布,我想确保无法检索到实际的IP。所以我需要一些IP地址的单向映射,以确保1-1映射。
如果我理解正确,那么MD5,SHA1或SHA256可能是一个解决方案。我想知道它们在处理方面是否不太贵?
我对任何解决方案感兴趣,但是如果Perl中的实现更好。
答案 0 :(得分:6)
我认为MD5会好又快。您需要添加一些常量的salt字符以避免彩虹表/ Web查找。例如,字符串“127.0.0.1”有md5 f528764d624db129b32c21fbca0cb8d6,它有相当多的谷歌点击。另一方面,“szabgab127.0.0.1”得到“你的搜索 - 501ff2fbdca6ee72247f8c61851f17b9 - 与任何文件都不匹配”(直到我发布这个答案......)
答案 1 :(得分:1)
使用Rabin fingerprinting。它实施起来快速而简单。
给定n位消息m 0 ,...,m n-1 ,我们 将其视为度数为n-1的多项式 在有限域GF(2)上。
然后我们选择一个随机的不可减少的 k次多项式p(x) GF(2),我们定义指纹 m为余数r(x)之后 在GF(2)上用p(x)除f(x) 可以看作是多项式 度k-1或k位数。
请注意,这仍然不是您所寻求的perfect hash function,但要获得一个,您可能会遇到能够破解该功能并从哈希获取原始IP的问题。在大多数情况下,指纹识别中碰撞的可能性极低是可以接受的。
另请注意,无论您最终使用哪种散列函数,如果您的散列函数已知,找到来自给定IP地址的日志条目将是微不足道的。如果你想要保护自己不受此限制,你应该加密哈希值。
答案 2 :(得分:1)
在@marcog和@daxim的答案的基础上,你可以使用HMAC,例如HMAC-SHA,在日志生成设备上使用硬编码的密钥。如果秘密漏掉了,那么这个方案就变得和迄今为止给出的任何一个一样弱。
或者,或许更简单地说,您可以使用相同的密钥概念来加密IP地址。 AES的128位块大小非常适合确保所有可能IP地址的1-1映射。只需在ECB模式下使用AES。
答案 3 :(得分:0)
⚠不要再使用MD5或SHA-1了。 ⚠请参阅文章了解其缺点。
使用salted SHA-2代替,Crypt::SaltedHash提供了一个很好的抽象。推荐的Perl绑定是Digest::SHA并使用XS。
你谈的是昂贵的。你有没有对代码进行分析?代码还没写?那就是too early to think about optimisation。安全必须是第一个问题。
编辑:示例代码
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);
答案 4 :(得分:0)
如果你只是使用哈希,那么有人可以进行蛮力攻击。
最简单的方法是使用Bloom Filter。特别是,http://www.afflib.org/处的C ++ Bloom过滤器实现允许您向Bloom过滤器添加任意字符串,然后进行探测以查看它们是否存在。如果你想要防止蛮力攻击,只需提高你的假阳性频率,使其达到十亿分之一。那么你将拥有唯一性,但人们将无法确定你所看到的IP地址。
答案 5 :(得分:0)
另一个选项是Crypt::Eksblowfish::Bcrypt。然而,它“更好”的原因恰恰是因为它是(eks)沉思 - 多么昂贵可调 - 这使得破解尝试从某种程度上变得荒谬可笑。对于您的应用程序,您可以缓存加密的IP,以便在至少看到重复项时不会很慢。