【问题标题】:How to generate a secure activation string in php?如何在 php 中生成安全的激活字符串?
【发布时间】:2010-10-26 22:38:37
【问题描述】:

用户订阅我的网站的电子邮件后。我的网站将生成一封电子邮件确认并发送给他们。在电子邮件内容中,我需要包含激活密钥,例如:

www.domain.com/activate.php?key=$generatedKey

如何生成密钥?使用 sha1($email)??

生成密钥后,我将其存储在数据库中,这样当用户单击链接时,我可以使用数据库验证它??我是新手,请指教..我需要一个电子邮件确认脚本..

【问题讨论】:

    标签: php email auto-generate confirmation


    【解决方案1】:

    就个人而言,我只是使用以下组合:

    $generatedKey = sha1(mt_rand(10000,99999).time().$email);
    

    冲突的可能性很小,但我建议在发送之前先检查您的数据库(使用 UNIQUE 约束是一种简单的方法)。

    【讨论】:

    • 如果您也将用户 ID 添加到 URL 并检查它们是否匹配,则不会发生冲突。
    • @Eli,有机会,因为某些字符集合确实散列到相同的散列字符串。虽然机会微乎其微(但仍然存在)。
    • 呃,我不喜欢向用户透露主键信息。但这是个好主意,伊莱。所以key=$generatedKey&id=$uid
    • 酷.. 用户帐户激活后,我应该删除激活密钥吗?如果用户想取消订阅,怎么办?
    • 是的,我会设置它,以便激活键只工作一次。如果您需要另一个,请生成一个新的。还有亚历克斯,我认为这与这里无关——我们只是将哈希用作随机字符生成器
    【解决方案2】:

    你基本上有几个选择:

    1) 创建一个看似随机的唯一标识符,并将其存储在与用户名对应的数据库中

    2) 生成随机密码,并在链接中包含用户名和密码,并将密码存储在数据库中

    3) 使用单向散列函数(md5、sah1 等)和秘密标识符来加密用户标识符。您不必将加密的用户标识符存储在数据库中。

    选项 1 很困难,因为您必须担心检查数据库以查看密钥是否已存在。但是,URL 不包含被激活的用户名,这很好。

    如果您将来已经打算使用某种数据库来存储用户信息(可能至少是密码),您可以选择选项 2。在您的数据库中添加另一列并不需要太多时间数据库。发送电子邮件时,将用户名和类似 $key = sha1(rand(1, 99999) . $username) 的内容保存在包含用户名的行的另一列中。然后让你的链接看起来像这样:http://you.com/activation.php?user=$username&key=$key。在activation.php 中,您检查键是否等于存储在数据库中的值。

    如果您想在数据库中使用更少的存储空间,选项 3 将起作用。您可以使用类似 $key = sha1($mysecret . $username) 作为秘密标识符。使用只有你知道的奇怪的东西作为 $mysecret,例如 'aaafj_my_secret_adfaf'。使用与选项 2 中相同类型的 URL。但是,由于您可以仅根据 $username 生成 $key,因此您不需要存储它。因此,当您在activation.php 中进行处理时,只需检查是否 sha1($mysecret . $_GET[username]) == $_GET[key]。如果是这样,您就知道您拥有正确的用户。从理论上讲,只要注册足够多,有人就可以计算出您对 $mysecret 的价值并生成激活密钥。但是,您肯定会注意到在他们开始计算它之前需要进行数十亿或更多的注册。所需的激活次数取决于散列函数的密钥大小。使用 sha1(160 位)与 md5(128 位)更难猜测您的 $mysecret 值。

    【讨论】:

    • 很好地总结了选项及其优缺点!我只想补充一点,无论您选择哪个选项,都有一些“不变量”适用于所有选项。例如: 1. 激活链接必须是唯一的,作为一个整体,因为如果不是,您无法分辨要激活哪个用户。 2.您必须至少在您的数据库中存储电子邮件地址,并且它也必须是唯一的。在这个观点中,第一个选项的缺点与其说是缺点,不如说是你最终会检查唯一性(至少是电子邮件地址的唯一性)。
    【解决方案3】:
    $guid=md5(uniqid(mt_rand(), true));
    

    【讨论】:

      【解决方案4】:

      如果您将激活字符串存储在数据库中并稍后检查,则根本不需要哈希!

      你只需要一个很长的随机字符串。你可以随心所欲地生成它,只要让它变长。事实上,理想情况下,它应该与电子邮件或用户名完全无关。

      【讨论】:

      • 这就是为什么 sha1、md5 和其他 crypt 函数很好,因为它们创建看似随机的字符串。如果您想要唯一的字符串(低冲突),最好的办法是基于一些唯一的常量(电子邮件)和一些额外的加盐。
      • 哈希函数不添加任何熵,因此在这种情况下它们不会或多或少地发生冲突。它们只是看起来对我们人类来说更加随机。
      【解决方案5】:

      应该可以,但是您可以通过添加一些盐来改进它,例如:

      $key = sha1($email . 'doYouLikeSauce');
      

      其他方法只是生成一个随机密码并通过电子邮件发送。

      【讨论】:

        【解决方案6】:
        $code = md5($_POST['username'] . microtime()); 
        

        【讨论】:

          猜你喜欢
          • 2011-10-16
          • 1970-01-01
          • 1970-01-01
          • 2015-09-18
          • 1970-01-01
          • 2015-11-07
          • 2011-10-30
          • 2016-08-27
          • 2012-02-12
          相关资源
          最近更新 更多