如何在php中生成安全的激活字符串?

19 php email confirmation auto-generate

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

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

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

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

St.*_*son 25

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

$generatedKey = sha1(mt_rand(10000,99999).time().$email);
Run Code Online (Sandbox Code Playgroud)

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

  • 没有碰撞的可能性是您也将用户ID添加到URL并检查它们是否匹配. (5认同)
  • 呃,我不喜欢向用户透露主要密钥信息.但这是个好主意,Eli.所以key = $ generatedKey&id = $ uid (3认同)

小智 8

你基本上有几个选择:

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位)vs md5(128位)可以更难猜测$ mysecret值.