我正在编写一个Perl电子邮件订阅管理应用程序,基于包含两个键码参数的URL。在订阅时,脚本将为每个订阅者创建两个在数据库中唯一的密钥代码(请参阅下面的脚本示例)。
将使用Digest :: SHA qw(sha256_hex)创建代码。我对它的理解是,确保代码不在数据库中重复的一种方法是在要编码的原始数据中创建唯一的前缀。 (见下文)。
一旦有人订阅,我就会拥有一个拥有两个“代码”字段的人的数据库记录,每个字段包含数据库中唯一的值。每个值都是一个长度为64个字符的字母数字字符串,使用小写(仅?)a-z和0-9,例如:
code1:ae7518b42b0514d69ae4e87d7d9f888ad268f4a398e7b88cbaf1dc2542858ba3
code2:71723cf0aecd27c6bbf73ec5edfdc6ac912f648683470bd31debb1a4fbe429e8
这些代码在简报电子邮件中作为订阅管理网址中的参数发送。因此,该人不必登录来管理他们的订阅;但只需点击网址。
我的问题是:
如果订阅者试图猜测另一个人的代码对的值,那么有多少种可能的组合不仅可以正确地猜测代码1,还可以猜测代码2?我想,就像彩票一样,一个人可以幸运,只猜两个;但我想了解这种可能性及其对安全的影响。
如果猜到组合,该人将获得对数据库的访问权;因此,我试图确定这种方法提供的安全级别,与用户名和8字符密码的更常规方法相比(一般来说,它本身可以被认为是两个关键代码,但比上面的64个字符短得多。 )
我也欢迎任何关于此方法的整体安全性的反馈。我注意到许多很多电子邮件简报似乎都使用类似的密钥代码,并且不需要登录取消订阅等。对于,主要问题(除了易用性)是一个人不应该取消订阅某人其他
谢谢!
Peter(请参阅下面的代码生成代码段)
请注意,每个ID和电子邮件都是唯一的。 密码是一个“系统”密码,对每个人来说都是一样的。
#!/usr/bin/perl use Digest::SHA qw(sha256_hex); $clear = `clear`; print $clear; srand; $id = 1; $email = 'someone@domain.com'; $tag = ':!:'; $password = 'z9.4!l3tv+qe.p9@'; $rand_str = '9' x 15; $rand_num = int(rand( $rand_str )); $time = time() * $id; $key_data = $id . $tag . $password . $rand_num . $time; $key_code = sha256_hex($key_data); $email_data = $email . $tag . $password . $time . $rand_num; $email_code = sha256_hex($email_data); print qq~ ID: $id EMAIL: $email KEY_DATA: $key_data KEY_CODE: $key_code EMAIL_DATA: $email_data EMAIL_CODE: $email_code ~; exit;
答案 0 :(得分:2)
防止第三方取消订阅某人似乎很复杂。为什么不为每个用户生成一个随机代码,并将其与用户名一起存储在数据库中?您正在使用的方法会创建一长串数字,但实际上并没有多少随机性。 SHA是一种确定性算法,可以彻底地对位进行加扰,但它不会添加熵。
对于N位真正的随机数,攻击者每次只有1 /(2 ^ N)的机会猜对。即使有少量的熵,比如说64位,你的服务器应该在攻击者获得成功的可能性很久之前限制来自攻击IP地址的取消订阅请求。他们可以更好地猜测用户的电子邮件密码,或拦截传输中未加密的电子邮件。
这就是为什么取消订阅代码通常很短。不需要长代码,长URL更容易被截断或输入错误。
答案 1 :(得分:1)
如果你问“猜测”两个256位“数字”是多么困难,那么得到你想要攻击的一个特定的人,那就是2 ^ 512:1。如果数据库中有1000个用户,并且攻击者并不关心他/她是哪个用户,那就是2 ^ 512:1000反对 - 不是可能性发生重大变化。
然而,如果你的攻击者要么控制你的机器中的一个邮件服务器到用户的机器,或者控制着沿途的任何路由器,那么它就比你的攻击者要简单得多。因为你的电子邮件是以纯文本形式发出的看到电子邮件数据包通过的合适的黑客能够看到你嵌入的URL,无论它有多少位。
与许多安全问题一样,这取决于付出多少努力。密码很好用户期望它们,因此发送需要输入密码的URL并不是一个重大障碍。如果您的URL甚至只是一个SHA密钥与密码挑战相结合,这几乎可以消除对您的电子邮件的中间人攻击。由你来决定是否值得。便宜,方便,安全。选一个。 : - )
更多的努力是使用客户端的公钥(而不是您的私人密码)对您的电子邮件进行gpg加密。明显的缺点是gpg(或pgp)显然很少使用,普通用户不太可能设置它。同样,这将完全消除MITM攻击,并且不需要密码,因为它基本上使用客户端gpg私钥密码。
答案 2 :(得分:1)
您基本上为给定的用户电子邮件ID生成了1e15个不同的可能哈希值(一旦与可能猜到的其他信息相结合)。您也可以只提供相同长度的十六进制编码随机数,并要求“取消订阅”链接包含要取消订阅的电子邮件地址或用户ID。
我怀疑任何人都会花费1至1e15的数字来猜测一个数字,特别是如果您对限制取消订阅请求进行评分,并发送“谢谢,有人取消订阅”电子邮件,如果有人取消订阅,并提出新的子订阅链接到那个。
生成随机字符串的快捷方法是:
my $hex = join '', map { unpack 'H*', chr(rand(256)) } 1..8;
print $hex, "\n";
b4d4bfb26fddf220
(这会给你2 ^ 64,或大约2 * 10 ^ 19组合。或者如果你加价限制'很多'。