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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17710897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:19:00  来源:igfitidea点击:

How to use SHA1 encryption instead of BCrypt in Laravel 4?

phplaravel

提问by dynamitem

I'm developing a so called AAC (Automatic Account Creator) for a game, it's basically a site with functions to create accounts, players and several more things for players. The server only supports SHA1 and plain - which is totally unsafe. I can't dive into the source code and make changes. If there's anyway to use SHA1 I would be grateful. I just read about BCrypt, it's great but I can't really change the source code to suit BCrypt. I managed to put SHA1 on registration like this:

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

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

But I simply can't login. am I doing it wrong? seems like Laravel won't let me login.

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

I've got get_registerand post_register, also I've got get_loginand post_login. Do i need to change something in the post_login to make it login or? any hints?

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

I'm using Laravel's php server (php artisan serve) and phpMyAdmin on WAMP. I think Laravel checks when you are checking the DB via the Auth::attemptmethod laravel is doing some form of hashing to check the current pw and the logged in one to check against each other.

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

回答by rmobis

You'll have to rewrite the Hashmodule. Thanks to Laravel's ideas of following IoC and Dependency Injection concepts, it'll be relatively easy.

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

First, create a app/librariesfolder and add it to composer's autoload.classmap:

首先,创建一个app/libraries文件夹并将其添加到 composer's autoload.classmap

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

        "app/libraries"
    ]
},

Now, it's time we create our class. Create a SHAHasherclass, implementing Illuminate\Hashing\HasherInterface. We'll need to implement its 3 methods: make, checkand needsRehash.

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

Note:On Laravel 5, implement Illuminate/Contracts/Hashing/Hasherinstead of Illuminate\Hashing\HasherInterface.

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

app/libraries/SHAHasher.php

应用程序/库/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;
    }

}

Now that we have our class done, we want it to be used by default, by Laravel. To do so, we'll create SHAHashServiceProvider, extending Illuminate\Support\ServiceProvider, and register it as the hashcomponent:

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

app/libraries/SHAHashServiceProvider.php

应用程序/库/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');
    }

}

Cool, now all we have to do is make sure our app loads the correct service provider. On app/config/app.php, under providers, remove the following line:

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

'Illuminate\Hashing\HashServiceProvider',

Then, add this one:

然后,添加这个:

'SHAHashServiceProvider',

回答by Das123

It took me a lot of time to get something similar happening in Laravel 5.6 but this thread was invaluable. The accepted answer gets you very close but there are still some ambushes along the way (as can be seen in the comments) so instead of struggling with the comments I thought it would be helpful for others to have it presented as an answer.

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

In my case I needed to access an existing database and couldn't change the user file. The passwords were saved in SHA256 format with a hash key applied as well. So the objective for me was to really only get the check function working.

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

I'm really new to Laravel and I know there will be a better way around this issue but I couldn't get the app\Librariesarea to register so I put both SHAHasher.phpand SHAHashServiceProvider.phpinto app\Providerswhich I would assume is some sort of Laravel sacrilege but it was the only way I got it to work. :)

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

The steps I took (hiHymaning rmobis'sexcellent answer for Laravel 4) was:

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

The hash key used in the original app needed to be accessed by Laravel so I added this to the bottom of .env.

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

.env

.env

...
HASH_KEY=0123_key_code_added_here_xyz

app/Providers/SHAHasher.php

应用程序/提供商/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

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/config/app.php

应用程序/配置/app.php

remove or comment out // Illuminate\Hashing\HashServiceProvider::class,

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

Add App\Providers\SHAHashServiceProvider::class,

添加 App\Providers\SHAHashServiceProvider::class,

I didn't need to register the users (only to allow them to use their existing logins to get in) so I only tested it for access. I'm not sure why the app/Libraries area wouldn't take. I was getting an error

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

Class 'SHAHashServiceProvider' not found

when I ran the composer dump-autoloadcommand until I moved both into app/Providers.

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

Hope this helps others trying to get the anser to work in Laravel 5.

希望这可以帮助其他人尝试让 anser 在 Laravel 5 中工作。

回答by Benubird

There is actually a easier (or more simple, at least) solution for a case like this. you can 'fake' the hashing, by using this method in the user model:

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

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

And hashing the input with your own hash function. For instance, if your passwords are currently hashed with sha1, you can validate the user with

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

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

It doesn't feellike good coding practice, to do it this way, but it will certainly be easier than rewriting the hash module.

以这种方式进行编码感觉并不是很好的编码习惯,但它肯定比重写哈希模块更容易。

回答by Лутовинов Алексей

Laravel 7 UPD

Laravel 7 UPD

same as Das123 answer but a little fix to

与 Das123 的答案相同,但有一点修复

app/Providers/SHAHashServiceProvider.php

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

}