RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 654760
Accepted
Floyat
Floyat
Asked:2020-04-17 19:57:46 +0000 UTC2020-04-17 19:57:46 +0000 UTC 2020-04-17 19:57:46 +0000 UTC

PHP 用户密码哈希生成

  • 772

我想知道如何进行用户密码恢复,但不使用数据库来存储为密码恢复链接生成的哈希值。也不可能以其他方式存储散列。

从基本条件:

  1. 该链接仅对当前电子邮件和用户密码有效(更准确地说,对于密码哈希,因为只有它存储在数据库中)

  2. 链接仅在创建后 24 小时内有效

如果没有第二点,那么可以简单地以某种方式从当前邮件和用户密码生成一个散列 + 从服务器端添加一些秘密字符,然后检查用户提供的散列。

但是第二点呢?如果我们在哈希中替换另一个时间戳,它将不起作用。

php
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. mydls1
    2020-04-17T20:11:56Z2020-04-17T20:11:56Z

    我不这么认为。我会解释为什么:1)所有静态数据存储源,例如将哈希写入文件,都可以被认为是一种基础,这是浪费时间。2)也许写入会话的选项适合您,首先不安全,其次也不实用。因为用户可以从一台计算机发出请求,然后从另一台计算机访问链接。但是如果是大学的一类问题,那么你可以这样实现,只需要保持session 24小时就可以解决没有时间的问题

    如果这对您来说并不困难,请解释您为什么需要这辆自行车?

    补充(作者评论后)

    想到一个无神的拐杖,只要用户恢复密码并且不登录系统,它就会起作用(因为你可以知道当前密码,只需点击恢复)

    哈希数据库中的整个字符串 + 密码恢复过程开始的字段(我们不存储哈希)

    之后,当点击链接时,我们将数据库中的所有行一一散列,并将每一行与到达 url 的散列进行比较(如果用户尚未登录,则数据库中的行没有更改,即,散列将是相同的),我们找到一个匹配项,我们在数据库中查找恢复开始标记,将其与当前日期(链接的 24 小时)进行比较,如果还不到 24 小时就做一些事情。 ..

    这是逻辑

    • 1
  2. chernomyrdin
    2020-04-17T20:20:12Z2020-04-17T20:20:12Z

    我们采用包含以下内容的数据结构:

    1. email
    2. TTL
    3. Новый пароль
    

    我们加密所有这些——我们得到一个散列,我们将散列提供给用户

    收到哈希后,我们对其进行解密,检查 TTL 和电子邮件是否存在,更改密码

    • 0
  3. Best Answer
    Floyat
    2020-04-18T17:00:23Z2020-04-18T17:00:23Z

    我自己找到了出路。

    解决方案#1。如果链接有效期超过一天,则不是最好的。

    $email      = 'email@mail.ru';
    $hashPass   = 'текущий_хэш_пароля_из_бд';
    
    //хэш, который будет отправлен пользователю вместе с ссылкой
    $hash       = md5($email.$hashPass.time());
    
    echo "http://mysite.ru/restore?hash=".$hash.'<br>';
    
    //так будет выглядеть проверка корректности хэша
    $time       = time();
    for ($i = 0; $i <= 86400; $i++){
        if ($hash === md5($email.$hashPass.($time - $i))){
            echo 'Хэш совпадает!';
            break;
        }
    }
    

    解决方案 #2。使用对称加密。

    function base64_url_encode($input) {
        return strtr(base64_encode($input), '+/=', '-_,');
    }
    
    function base64_url_decode($input) {
        return base64_decode(strtr($input, '-_,', '+/='));
    }
    
    function my_encode($data,$key,$iv){
        $enc = $data.openssl_encrypt(time(), "AES-128-CBC", $key, OPENSSL_RAW_DATA, $iv);
        return base64_url_encode($enc);
    }
    
    function my_decode($data,$key,$iv){
        $enc = openssl_decrypt($data, "AES-128-CBC", $key, OPENSSL_RAW_DATA, $iv);
        return $enc;
    }
    
    $appCodeKey = '16CodeKeySymbols'; //Initialization Vector для openssl_encrypt/openssl_decrypt
    $email      = 'email@mail.ru';
    $hashPass   = 'текущий_хэш_пароля_из_бд';
    //md5 для примера, можно изменить на другие более криптостойкие алгоритмы
    $key        = md5($email); 
    $hash       = md5($email.$hashPass);
    
    $encode     = my_encode($hash,$key,$appCodeKey);    
    
    echo "http://mysite.ru/restore?hash=".$encode.'<br>';
    
    //проверка корректности хэша
    $decode     = base64_url_decode($encode,$key,$appCodeKey);
    
    $dec_hash   = substr($decode,0,32);
    $dec_time   = my_decode(substr($decode,32),$key,$appCodeKey);
    
    if ($dec_hash === $hash && $dec_time >= time() - 86400){
        echo 'Корректный хэш';
    }
    

    当然,它可以更容易或有所改变,没有必要在第二个选项中散列或以明文形式发送电子邮件作为第二个参数。

    决定 #3。

    $ts = strtotime("+1 day");
    $link = "http://mysite.ru/restore?email=".urlencode($email)."&ts=$ts&hash=".md5($pass_hash.$email.$ts);
    

    这项任务的本质是理论上的,而不是实际的部分。 这会起作用。这就是我想要实现的目标。

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5