18

我正在为游戏开发一个所谓的 AAC(自动帐户创建器),它基本上是一个具有创建帐户、玩家和其他玩家功能的网站。服务器只支持 SHA1 和 plain - 这是完全不安全的。我无法深入研究源代码并进行更改。如果有任何使用 SHA1 的方法,我将不胜感激。我刚刚阅读了有关 BCrypt 的内容,它很棒,但我无法真正更改源代码以适应 BCrypt。我设法将 SHA1 注册为这样:

$password = $input['password'];
$password = sha1($password);

但我根本无法登录。我做错了吗?好像 Laravel 不会让我登录。

我有get_registerpost_register,我也有get_loginpost_login。我需要更改 post_login 中的某些内容以使其登录吗?任何提示?

我在 WAMP 上使用 Laravel 的 php 服务器(php artisan serve)和 phpMyAdmin。我认为 Laravel 在您通过以下Auth::attempt方法检查数据库时会进行检查,laravel 正在执行某种形式的散列来检查当前密码和登录密码以相互检查。

4

6 回答 6

42

您将不得不重写Hash模块。由于 Laravel 遵循 IoC 和依赖注入概念的想法,它会相对容易。

首先,创建一个app/libraries文件夹并将其添加到作曲家的autoload.classmap

"autoload": {
    "classmap": [
        // ...

        "app/libraries"
    ]
},

现在,是时候创建我们的类了。创建一个SHAHasher类,实现Illuminate\Hashing\HasherInterface. 我们需要实现它的 3 个方法makecheckneedsRehash

注意:在 Laravel 5 上,实现Illuminate/Contracts/Hashing/Hasher而不是Illuminate\Hashing\HasherInterface.

应用程序/库/SHAHasher.php

class SHAHasher implements Illuminate\Hashing\HasherInterface {

    /**
     * Hash the given value.
     *
     * @param  string  $value
     * @return array   $options
     * @return string
     */
    public function make($value, array $options = array()) {
        return hash('sha1', $value);
    }

    /**
     * Check the given plain value against a hash.
     *
     * @param  string  $value
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function check($value, $hashedValue, array $options = array()) {
        return $this->make($value) === $hashedValue;
    }

    /**
     * Check if the given hash has been hashed using the given options.
     *
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function needsRehash($hashedValue, array $options = array()) {
        return false;
    }

}

现在我们已经完成了我们的类,我们希望 Laravel 默认使用它。为此,我们将创建SHAHashServiceProvider、扩展Illuminate\Support\ServiceProvider并将其注册为hash组件:

应用程序/库/SHAHashServiceProvider.php

class SHAHashServiceProvider extends Illuminate\Support\ServiceProvider {

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register() {
        $this->app['hash'] = $this->app->share(function () {
            return new SHAHasher();
        });

    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides() {
        return array('hash');
    }

}

很酷,现在我们要做的就是确保我们的应用程序加载正确的服务提供商。在app/config/app.php,在 下providers,删除以下行:

'Illuminate\Hashing\HashServiceProvider',

然后,添加这个:

'SHAHashServiceProvider',
于 2013-07-18T09:27:57.373 回答
7

我花了很多时间才在 Laravel 5.6 中发生类似的事情,但这个线程非常宝贵。接受的答案让您非常接近,但沿途仍然有一些伏击(如评论中所见),因此与其为评论而苦苦挣扎,我认为将其作为答案提出对其他人会有所帮助。

就我而言,我需要访问现有数据库并且无法更改用户文件。密码以 SHA256 格式保存,并应用了哈希密钥。所以我的目标是真正让检查功能正常工作。

我对 Laravel 真的很陌生,我知道会有更好的方法解决这个问题,但我无法app\Libraries注册该区域,所以我将SHAHasher.phpSHAHashServiceProvider.php都放入app\Providers其中,我认为这是某种 Laravel亵渎神明,但这是我让它发挥作用的唯一方法。:)

我采取的步骤(劫持rmobis对 Laravel 4 的出色回答)是:

Laravel 需要访问原始应用程序中使用的哈希键,所以我将其添加到.env.

.env

...
HASH_KEY=0123_key_code_added_here_xyz

应用程序/Providers/SHAHasher.php

namespace App\Providers;

use Illuminate\Contracts\Hashing\Hasher;

class SHAHasher implements Hasher
{

  /**
   * Get information about the given hashed value.
   * TODO: This was added to stop the abstract method error.
   *
   * @param  string  $hashedValue
   * @return array
   */
  public function info($hashedValue)
  {
    return password_get_info($hashedValue);
  }

  /**
   * Hash the given value.
   *
   * @param  string $value
   * @return array   $options
   * @return string
   */
  public function make($value, array $options = array())
  {
    // return hash('sha1', $value);
    // Add salt and run as SHA256
    return hash_hmac('sha256', $value, env('HASH_KEY'));
  }

  /**
   * Check the given plain value against a hash.
   *
   * @param  string $value
   * @param  string $hashedValue
   * @param  array $options
   * @return bool
   */
  public function check($value, $hashedValue, array $options = array())
  {
    return $this->make($value) === $hashedValue;
  }

  /**
   * Check if the given hash has been hashed using the given options.
   *
   * @param  string $hashedValue
   * @param  array $options
   * @return bool
   */
  public function needsRehash($hashedValue, array $options = array())
  {
    return false;
  }

}

app/Providers/SHAHashServiceProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class SHAHashServiceProvider extends ServiceProvider {

  /**
   * Register the service provider.
   *
   * @return void
   */
  public function register() {
    $this->app->singleton('hash', function() {
      return new SHAHasher();
    });
  }

  /**
   * Get the services provided by the provider.
   *
   * @return array
   */
  public function provides() {
    return array('hash');
  }

}

应用程序/配置/app.php

删除或注释掉// Illuminate\Hashing\HashServiceProvider::class,

添加App\Providers\SHAHashServiceProvider::class,

我不需要注册用户(只允许他们使用现有的登录名进入),所以我只测试了它的访问权限。我不确定为什么应用程序/库区域不会占用。我收到一个错误

Class 'SHAHashServiceProvider' not found

当我运行composer dump-autoload命令直到我将两者都移到应用程序/提供程序中时。

希望这有助于其他试图让分析器在 Laravel 5 中工作的人。

于 2018-05-29T03:46:18.553 回答
5

对于这样的情况,实际上有一个更简单(或更简单,至少)的解决方案。您可以通过在用户模型中使用此方法来“伪造”散列:

public function getAuthPassword() {
    return Hash::make($this->password);
}

并使用您自己的哈希函数对输入进行哈希处理。例如,如果您的密码当前使用 sha1 进行哈希处理,您可以使用

Auth::attempt(array('email' => $email, 'password' => sha1($password))

这样做感觉不是很好的编码实践,但肯定比重写哈希模块更容易。

于 2014-05-01T14:21:38.417 回答
3

Laravel 7 方式

在 Laravel 7 中,向 Laravel 添加新的哈希方法变得容易得多,您仍然可以支持旧的哈希方法,而不是基本上覆盖它们。

首先,我们将在 app 文件夹中创建一个名为 Libs 或 Libaries 的子文件夹,或者基本上任何您想调用的文件夹。在那个文件夹中,我创建了一个名为 CustomHash 的文件夹,其中存储了我所有的自定义哈希。

通过 PSR-4 会自动检测到它,我们不需要在任何地方添加它。

命名空间基于我选择的文件夹名称。

应用程序/AppServiceProvider.php

首先我们使用 Sha1Hasher 的命名空间

use App\Libs\CustomHash\Sha1Hasher;

然后在 AppServiceProvide.php 的 boot() 函数中

        Hash::extend("sha1", function($app)
        {
            return new Sha1Hasher();
        });

应用程序/Libs/CustomHash/Sha1Hasher.php

<?php

    namespace App\Libs\CustomHash;

    use Illuminate\Contracts\Hashing\Hasher as HasherContract;
    use Illuminate\Hashing\AbstractHasher;

    class Sha1Hasher extends AbstractHasher implements HasherContract {

        /**
         * Hash the given value.
         *
         * @param  string  $value
         * @return array   $options
         * @return string
         */
        public function make($value, array $options = array()) {
            //I have custom encoding / encryption here//
            //Define your custom hashing logic here//
            return sha1($value);
        }

        /**
         * Check the given plain value against a hash.
         *
         * @param  string  $value
         * @param  string  $hashedValue
         * @param  array   $options
         * @return bool
         */
        public function check($value, $hashedValue, array $options = array()) {
            return $this->make($value) === $hashedValue;
        }

        /**
         * Check if the given hash has been hashed using the given options.
         *
         * @param  string  $hashedValue
         * @param  array   $options
         * @return bool
         */
        public function needsRehash($hashedValue, array $options = array()) {
            return false;
        }

    }



如果您想更改所有内容的默认哈希算法,基本上就是这样,还有一件事要做:

配置/哈希.php

将哈希的默认驱动程序更改为我们通过上述编辑实现的 sha1 驱动程序。

    'driver' => 'sha1',

于 2020-08-05T01:50:58.047 回答
0

你可以这样做


dd(
sha1(55),
hash('sha1', 55),
hash_hmac('sha1', 55, env('APP_KEY')),
hash_hmac('sha256', 55, env('APP_KEY')),
hash_hmac('sha512', 55, env('APP_KEY')),
);

// outputs:
/*
"8effee409c625e1a2d8f5033631840e6ce1dcb64"
"8effee409c625e1a2d8f5033631840e6ce1dcb64"
"a2ebb15e6747d1c09f2754787ab390d35c24996e"
"f0fadaa9fdd518947ac3f698196d5370dc2409bbdfbe9e37bd30f935b6cc1f47"
"c1e6f4e144565aa4fdb9c7ae34aba7d43424e20fa40ad3a0641d20bfbb3b9681ded4f4cc8b4661804e4a753118a3f984585d6915ee6d4b75a95310af48afe920"
*/

于 2021-04-11T17:36:33.677 回答
-1

Laravel 7 升级版

与 Das123 答案相同,但对

app/Providers/SHAHashServiceProvider.php

namespace App\Libraries\ShaHash;

use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Hashing\AbstractHasher;

class SHAHasher extends AbstractHasher implements HasherContract

  /**
   * Register the service provider.
   *
   * @return void
   */
  public function register() {
    $this->app->singleton('hash', function() {
      return new SHAHasher();
    });
  }

  /**
   * Get the services provided by the provider.
   *
   * @return array
   */
  public function provides() {
    return array('hash');
  }

}
于 2020-04-18T08:50:22.200 回答