doushi3803 2018-11-08 15:20
浏览 63
已采纳

将加密方法从php转换为python [关闭]

So I'm trying to implement a system where user authentication is based on external sql.

This external sql is on my first website where I have a lot of users and I simply want them to login with the same credentials.

The passwords stored in the database are encrypted so I need to figure out the encryption method. I have full access to the website so I found this php code (site is based on php):

/**
 * Generate a password hash
 *
 * @param string $strPassword The unencrypted password
 *
 * @return string The encrypted password
 *
 * @throws \Exception If none of the algorithms is available
 */
public static function hash($strPassword)
{
    if (CRYPT_SHA512 == 1)
    {
        return crypt($strPassword, '$6$' . md5(uniqid(mt_rand(), true)) . '$');
    }
    elseif (CRYPT_SHA256 == 1)
    {
        return crypt($strPassword, '$5$' . md5(uniqid(mt_rand(), true)) . '$');
    }
    elseif (CRYPT_BLOWFISH == 1)
    {
        return crypt($strPassword, '$2a$07$' . md5(uniqid(mt_rand(), true)) . '$');
    }
    else
    {
        throw new \Exception('None of the required crypt() algorithms is available');
    }
}

and also this:

/**
 * Run the controller and parse the password template
 */
public function run()
{
    $this->Template = new BackendTemplate('be_password');

    if (Input::post('FORM_SUBMIT') == 'tl_password')
    {
        $pw = Input::postRaw('password');
        $cnf = Input::postRaw('confirm');

        // The passwords do not match
        if ($pw != $cnf)
        {
            Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']);
        }
        // Password too short
        elseif (utf8_strlen($pw) < Config::get('minPasswordLength'))
        {
            Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], Config::get('minPasswordLength')));
        }
        // Password and username are the same
        elseif ($pw == $this->User->username)
        {
            Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
        }
        // Save the data
        else
        {
            // Make sure the password has been changed
            if (crypt($pw, $this->User->password) === $this->User->password)
            {
                Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']);
            }
            else
            {
                $this->loadDataContainer('tl_user');

                // Trigger the save_callback
                if (is_array($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback']))
                {
                    foreach ($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'] as $callback)
                    {
                        if (is_array($callback))
                        {
                            $this->import($callback[0]);
                            $pw = $this->$callback[0]->$callback[1]($pw);
                        }
                        elseif (is_callable($callback))
                        {
                            $pw = $callback($pw);
                        }
                    }
                }

                $objUser = UserModel::findByPk($this->User->id);
                $objUser->pwChange = '';
                $objUser->password = Encryption::hash($pw);
                $objUser->save();

                Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']);
                $this->redirect('contao/main.php');
            }
        }

        $this->reload();
    }

My question is:

how to translate this method to python?

I don't quite understand the randomness and how to repeat it. Cou;ld someone explain?

Thanks,

C

//edit:

I mean I don't understand where

return crypt($strPassword, '$6$' . **md5(uniqid(mt_rand(), true))** . '$');

this middle part is saved and thus how can it ever be compared to crypt(password, the_same_function(but gives totally different value);

succesfully

I feel like I'm missing something obvious here, could someone explain? I know it's basic.

Thanks again

  • 写回答

1条回答 默认 最新

  • duangou2028 2018-11-08 16:27
    关注

    Main magic here is in 2 lines:

    the one that you mentioned:

    return crypt($strPassword, '$6$' . **md5(uniqid(mt_rand(), true))** . '$');
    

    and the one which checks if password is changed:

    if (crypt($pw, $this->User->password) === $this->User->password)
    

    in fist one the salt for the password is generated, in second hashed password from database is used to extract the salt which has to be used in crypt() method

    Here you have more info: http://php.net/manual/en/faq.passwords.php#faq.passwords.salt

    minus may be because you didn't put enough work at first and ( the thing that made it harder for me ) you didn't put your password verification code and you didn't put your python code.

    I think you have enough now to write your own code. Take a look in the python hashlib documentation https://docs.python.org/3/library/hashlib.html and using salts.

    I hope it's enough to get you going if not post your python code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?