Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 29.08.2016 02:43:29

Перенос сайта с MODX Revo на Laravel 5

Всем привет. Начал изучать Laravel, очень занятный фреймворк. Поставил стандартный Auth который идёт из коробки. Вопрос в следующем. В MODX Revo по умолчанию пароли юзеров хешируются в PBKDF2, а в Laravel 5.3 из коробки Auth хеширует пароли в bcrypt. Подскажите можно ли как-то конвертнуть пароли из одной системы шифрования в другую без потерь? Запасной вариант, если каких-то наработок нет, можно ли хешировать пароли в PBKDF2 и в загруженной таблице юзеров с MODX пароли оставить как есть и чтобы авторизация с регистрацией работала с PBKDF2?

Не в сети

#2 30.08.2016 11:24:04

Re: Перенос сайта с MODX Revo на Laravel 5

sequelone пишет:

Всем привет. Начал изучать Laravel, очень занятный фреймворк. Поставил стандартный Auth который идёт из коробки. Вопрос в следующем. В MODX Revo по умолчанию пароли юзеров хешируются в PBKDF2, а в Laravel 5.3 из коробки Auth хеширует пароли в bcrypt. Подскажите можно ли как-то конвертнуть пароли из одной системы шифрования в другую без потерь? Запасной вариант, если каких-то наработок нет, можно ли хешировать пароли в PBKDF2 и в загруженной таблице юзеров с MODX пароли оставить как есть и чтобы авторизация с регистрацией работала с PBKDF2?


Т.к. у вас уже есть база с паролями в виде PBKDF2, имеет смысл изменить способ шифрования в в вашем ларавел-приложении, чтобы он их шифровал также в PBKDF2


Вот две реализации шифрования PBKDF2
https://packagist.org/packages/vjroby/laravel-pbkdf2
https://packagist.org/packages/gponster/laravel-pbkdf2
Сам не проверял, извини.

В самом приложении надо будет поменять код создания записи в бд (по дефолту, кажется, в AuthController->create)
плюс сделать свой трейт, как реализацию Authenticatable, где введенный при логировании пароль будет шифроваться через PBKDF2 и сравниваться со строкой в БД

Изменено Diogen (30.08.2016 11:33:22)

Не в сети

#3 04.09.2016 17:26:10

Re: Перенос сайта с MODX Revo на Laravel 5

Diogen пишет:
sequelone пишет:

Всем привет. Начал изучать Laravel, очень занятный фреймворк. Поставил стандартный Auth который идёт из коробки. Вопрос в следующем. В MODX Revo по умолчанию пароли юзеров хешируются в PBKDF2, а в Laravel 5.3 из коробки Auth хеширует пароли в bcrypt. Подскажите можно ли как-то конвертнуть пароли из одной системы шифрования в другую без потерь? Запасной вариант, если каких-то наработок нет, можно ли хешировать пароли в PBKDF2 и в загруженной таблице юзеров с MODX пароли оставить как есть и чтобы авторизация с регистрацией работала с PBKDF2?


Т.к. у вас уже есть база с паролями в виде PBKDF2, имеет смысл изменить способ шифрования в в вашем ларавел-приложении, чтобы он их шифровал также в PBKDF2


Вот две реализации шифрования PBKDF2
https://packagist.org/packages/vjroby/laravel-pbkdf2
https://packagist.org/packages/gponster/laravel-pbkdf2
Сам не проверял, извини.

В самом приложении надо будет поменять код создания записи в бд (по дефолту, кажется, в AuthController->create)
плюс сделать свой трейт, как реализацию Authenticatable, где введенный при логировании пароль будет шифроваться через PBKDF2 и сравниваться со строкой в БД

Только заметил. Спасибо, не знал. В теории с Sentinel эти пакеты можно связать без велосипедостроения?

Не в сети

#4 20.12.2016 07:24:10

Re: Перенос сайта с MODX Revo на Laravel 5

Привет, по поводу шифрования PBKDF2, выдернул из самого Modx Revo классы хэширования ниже приведу код, может кому будет интересно и поможет:

<?php

namespace HashPassword;

abstract class Hash {

    public $host= null;

    public $options= array();

    function __construct(Hashing &$host, $options= array()) {
        $this->host =& $host;
        if (is_array($options)) {
            $this->options = $options;
        }
    }

    public function getOption($key, $options = null, $default = null) {
        if (is_array($options) && array_key_exists($key, $options)) {
            $option = $options[$key];
        } else {
            $option = $this->host->getOption($key, $this->options, $default);
        }
        return $option;
    }

    public abstract function hash($string, array $options = array());
}

<?php

namespace HashPassword;

class Hashing {

    public $options= array();

    protected $_hashes= array();


    function __construct($options= array()) {
        if (is_array($options)) {
            $this->options = $options;
        }
    }


    public function getOption($key, $options = null, $default = null) {
        if (is_array($options) && array_key_exists($key, $options)) {
            $option = $options[$key];
        } elseif (array_key_exists($key, $this->options)) {
            $option = $this->options[$key];
        } else {
            $option = $default;
        }
        return $option;
    }

    public function getHash($key, $class, $options = array())
    {
            if (empty($key)) {
                abort(400, 'Key not be empty');
            }

            if (!array_key_exists($key, $this->_hashes)) {
                $hash = new Pbkdf2($this, $options);
                if ($hash instanceof Pbkdf2) {
                    $this->_hashes[$key] = $hash;
                    $this->$key =& $this->_hashes[$key];
                }
            }
            if (array_key_exists($key, $this->_hashes)) {
                return $this->_hashes[$key];
            }
    }
}

<?php

namespace HashPassword;

class Pbkdf2 extends Hash {

    public function hash($string, array $options = array()) {
        $derivedKey = false;
        $salt = $this->getOption('salt', $options, false);
        if (is_string($salt) && strlen($salt) > 0) {
            $iterations = (integer) $this->getOption('iterations', $options, 1000);
            $derivedKeyLength = (integer) $this->getOption('derived_key_length', $options, 32);
            $algorithm = $this->getOption('algorithm', $options, 'sha256');

            $hashLength = strlen(hash($algorithm, null, true));
            $keyBlocks = ceil($derivedKeyLength / $hashLength);
            $derivedKey = '';
            for ($block = 1; $block <= $keyBlocks; $block++) {
                $hashBlock = $hb = hash_hmac($algorithm, $salt . pack('N', $block), $string, true);
                for ($blockIteration = 1; $blockIteration < $iterations; $blockIteration++) {
                    $hashBlock ^= ($hb = hash_hmac($algorithm, $hb, $string, true));
                }
                $derivedKey .= $hashBlock;
            }
            $derivedKey = substr($derivedKey, 0, $derivedKeyLength);
            if (!$this->getOption('raw_output', $options, false)) {
                $derivedKey = base64_encode($derivedKey);
            }
        } else {
            abort(400, 'PBKDF2 requires a valid salt string');
        }
        return $derivedKey;
    }
}

<?php

namespace HashPassword;

class Password
{
    protected static function getPbkdf2Instance ()
    {
        $hashing = new Hashing();
        $pbkdf2 = new Pbkdf2($hashing);

        return $pbkdf2;
    }
    
    public static function validate ($password, $safePassword, $salt)
    {
        $pbkdf2 = self::getPbkdf2Instance();

        $hash = $pbkdf2->hash($password, ['salt' => $salt]);

        if ($hash !== $safePassword) {
            return false;
        }

        return true;
    }
}

Не в сети

#5 23.12.2016 10:57:33

Re: Перенос сайта с MODX Revo на Laravel 5

про Sentinel не скажу, а родная ларавелевская авторизация допускает множество возможностей расширения. когда мне надо было авторизовать юзеров по базе древнего приложения (там пароли по старинке были в MD5), я просто добавил app/Services/AppUserProvider.php такого вида

<?php

namespace App\Services;

use App\User;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Support\Str;

class AppUserProvider extends EloquentUserProvider
{
    public function __construct()
    {
        parent::__construct(new MD5Hashing(), User::class);
    }

    public function retrieveByCredentials(array $credentials)
    {
        $query = $this->createModel()->newQuery();

        foreach ($credentials as $key => $value) {
            if (!Str::contains($key, 'password')) {
                $query->where($key, $value);
            } else {
                $query->where($key, $this->hasher->make($value));
            }
        }

        return $query->first();
    }
}

далее – хэшер app/Services/MD5Hashing.php

<?php

namespace App\Services;

use Illuminate\Contracts\Hashing\Hasher as HasherContract;

class MD5Hashing implements HasherContract
{
    /**
     * Hash the given value.
     *
     * @param  string $value
     * @param  array $options
     * @return string
     */
    public function make($value, array $options = [])
    {
        $hash = md5(md5($value));

        return $hash;
    }

    /**
     * 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 = [])
    {
        if (strlen($hashedValue) === 0) {
            return false;
        }

        return $this->make($value, $options) === $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 = [])
    {
        return false;
    }
}

теперь остаётся использовать AppUserProvider вместо стандартного, открываем app/Providers/AppServiceProvider.php

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app['auth']->provider('custom_provider', function () {
            return new AppUserProvider;
        });
    }
}

и находим в config/auth.php меняем

    'providers' => [
        'users' => [
            'driver' => 'custom_provider',
            'model' => App\User::class,
        ],
    ],

результат – приложение при авторизации использует небезопасный md5 вместо православного bcrypt smile

надеюсь вам это знание чем-то поможет в решение вашей задачи smile

Изменено constb (23.12.2016 10:58:31)

Не в сети

Подвал раздела