如何在Laravel 4中使用SHA1加密而不是BCrypt?

时间:2013-07-17 21:50:15

标签: php laravel

我正在为游戏开发一个所谓的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。我认为当你通过Auth::attempt方法检查数据库时,Laravel会检查是否正在进行某种形式的散列检查以检查当前的pw和登录的pw以进行相互检查。

6 个答案:

答案 0 :(得分:39)

您必须重写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.phpproviders下,删除以下行:

'Illuminate\Hashing\HashServiceProvider',

然后,添加以下内容:

'SHAHashServiceProvider',

答案 1 :(得分:5)

我花了很多时间在Laravel 5.6中发生类似的事情,但这个帖子非常宝贵。接受的答案会让你非常接近,但是在整个过程中仍然存在一些伏击(正如评论中所见),所以我没有对评论进行挣扎,而是认为将其作为答案呈现给其他人是有帮助的。

在我的情况下,我需要访问现有数据库,但无法更改用户文件。密码以SHA256格式保存,同时也应用了哈希密钥。所以我的目标是真正只让检查功能起作用。

我是Laravel的新手,我知道会有一个更好的方法解决这个问题,但我无法让app\Libraries区域注册,所以我把两个 SHAHasher.php SHAHashServiceProvider.php 进入app\Providers,我认为这是某种Laravel亵渎神灵,但这是我使用它的唯一方法。 :)

我采取的步骤(劫持 rmobis的 Laravel 4的优秀答案)是:

原始应用程序中使用的哈希密钥需要由Laravel访问,因此我将其添加到.env的底部。

<强> .ENV

...
HASH_KEY=0123_key_code_added_here_xyz

应用/提供者/ 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;
  }

}

应用/提供者/ 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命令直到我将它们都移到app / Providers中时。

希望这有助于其他人试图让他们在Laravel 5中工作。

答案 2 :(得分:4)

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

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

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

验证用户
Auth::attempt(array('email' => $email, 'password' => sha1($password))

它不像其他方式那样感觉这样做,但它肯定比重写哈希模块更容易。

答案 3 :(得分:1)

Laravel 7路

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

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

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

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

app / AppServiceProvider.php

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

use App\Libs\CustomHash\Sha1Hasher;

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

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

app / 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;
        }

    }



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

config / hashing.php

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

    'driver' => 'sha1',

答案 4 :(得分: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"
*/

答案 5 :(得分:-1)

Laravel 7 UPD

与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');
  }

}