使用防篡改措施验证“确认”电子邮件链接的防篡改方法?
Posted
技术标签:
【中文标题】使用防篡改措施验证“确认”电子邮件链接的防篡改方法?【英文标题】:Tamper proof way to verify a 'confirm' email link with preventive measures for tampering? 【发布时间】:2016-05-19 07:42:45 【问题描述】:背景故事: 我在我的网站上运行了一个 ePetition 类型的服务,我通过电子邮件向人们发送一个链接,他们可以在该链接中“同意”请愿书。此链接仅包含发送者的“petitionID”和“用户名”。
这些信息不是特别敏感,但我仍然要求它是防篡改的,因为我希望他们能够接受而无需登录或在数据库中存储值。
我想到了使用 Java 的 String.hashCode() 函数。
可能将网址设为:用户名、请愿书 ID,然后是哈希
www.website.com/accept.jsp?user='username'&id='petid'&token='1039678106'
令牌可以由用户名 + id(来自链接)+ datePetitionStarted(就像未在 url 中公开的盐一样)组成,例如:
String test = "mike.Who@petitionwebsite.com+1524+09/02/2016";
System.out.println(test.hashCode());
这将给我一个哈希值“1039678106”,这意味着服务器端,我可以获取 ID 参数、人员的用户名并使用 datePetitionStarted,获取哈希码并进行比较。
您认为这是防止篡改的有效方法吗?
我真的在追求一种接受请愿的象征性方法,所以如果有人有任何其他想法,那就太棒了。
谢谢,
迈克
【问题讨论】:
你需要一些秘密。可能最好使用 HMAC。 【参考方案1】:这就是我所做的(实际上是防篡改的)。我不使用 java 脚本,因为用户无论如何都可以禁用它。我只需创建一个 UUID(存储在用户详细信息旁边的数据库中),然后在注册过程中创建一个通过电子邮件发送的链接。
http://my_domain_name/Activate?key=6faeecf5-9ab3-46f4-9785-321a5bbe2ace
当用户点击上面的链接时,服务器端代码会检查这个密钥是否确实存在于数据库中,在这种情况下它会激活用户帐户。
【讨论】:
这是一个很好的解决方案,在数据库中存储哈希也是理想的,但不幸的是,我不希望用户通常必须登录或使用数据库。 这就是为什么他们的过期时间最好比成功暴力破解所需的时间短得多。例如。一小时。然后告诉客户“对不起,密钥已过期,点击重新生成一个,等等等等”。 @Satya 即使您猜到了 UUID,您仍然必须猜到用户凭据才能成功登录(仅 UUID 是不够的)。 @dsp_user 我没有说只使用 UUID 有人可以登录到其他人的帐户。我只是说它很容易猜到。 好吧,我以为你是这个意思。 :)【参考方案2】:虽然 String.hashcode() 可能会在多个实例中为相同的字符串返回相同的值,但这并不能保证。
每当在同一对象上多次调用它时 执行 Java 应用程序时,hashCode 方法必须一致 返回相同的整数,只要不使用 equals 中的信息 对象上的比较被修改。 这个整数不必保留 从应用程序的一次执行到另一次执行一致 相同的应用程序。
Object.hashcode 的 API 文档。
因此,如果您要沿着这条路线走下去,您应该使用自己的哈希。
【讨论】:
以上是关于使用防篡改措施验证“确认”电子邮件链接的防篡改方法?的主要内容,如果未能解决你的问题,请参考以下文章