Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/users/model/passwords/salted_md5.php
<?php
/**
 * This file implements the salted md5 Password Driver class.
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
 *
 * @package evocore
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );


load_class( 'users/model/passwords/_passworddriver.class.php', 'PasswordDriver' );

/**
 * saltedMd5PasswordDriver Class
 *
 * @package evocore
 */
class saltedMd5PasswordDriver extends PasswordDriver
{
    protected
$code = 'bb$H';

   
/**
     * Length of salt
     * @var integer
     */
   
protected $salt_length = 9;


   
/**
     * Hash password
     *
     * @param string Password
     * @param string Salt
     * @return string Hashed password
     */
   
public function hash( $password, $salt = '' )
    {
        if( empty(
$salt ) )
        {    
// Generate salt for new hashing:
           
$salt = $this->get_random_salt();
        }

        if( (
$count_log2 = $this->get_count_setting( $salt ) ) === false )
        {
           
// Return md5 of password if settings do not
            // comply with our standards. This will only
            // happen if pre-determined settings are
            // directly passed to the driver. The manager
            // will not do this. Same as the old hashing
            // implementation in phpBB 3.0
           
return md5( $password );
        }

       
$hash = md5( substr( $salt, 1 ).$password, true );
        do
        {
           
$hash = md5( $hash.$password, true );
        }
        while( --
$count_log2 );

        return
$this->hash_encode64( $hash, 16 );
    }


   
/**
     * Get JavaScript code to hash password on browser/client side
     *
     * @param string Name of password variable in JS code
     * @param string Name of salt variable in JS code
     * @return string
     */
   
public function get_javascript_hash_code( $var_password_name, $var_salt_name )
    {
       
$js_code = '
function salted_md5_hash_encode64( input, count )
{
    var output = "";
    var i = 0;
    var itoa64 = "'
.$this->itoa64.'";

    do
    {
        value = input[ i++ ].charCodeAt(0);
        output += itoa64[ value & 0x3f ];

        if( i < count )
        {
            value |= input[ i ].charCodeAt(0) << 8;
        }

        output += itoa64[ (value >> 6) & 0x3f ];

        if( i++ >= count )
        {
            break;
        }

        if( i < count )
        {
            value |= input[ i ].charCodeAt(0) << 16;
        }

        output += itoa64[ ( value >> 12 ) & 0x3f ];

        if( i++ >= count )
        {
            break;
        }

        output += itoa64[ ( value >> 18 ) & 0x3f ];
    }
    while( i < count );

    return output;
}

function salted_md5_get_count_setting( salt )
{
    if( salt == "" || salt.length != '
.$this->salt_length.' )
    {    // Wrong salt format:
        return false;
    }

    var itoa64 = "'
.$this->itoa64.'";
    var count_log2 = itoa64.indexOf( salt[0] );

    if( count_log2 < 7 || count_log2 > 30 )
    {    // Not allowed value:
        return false;
    }

    return 1 << count_log2;
}

function salted_md5_hash( password, salt )
{
    var count_log2 = salted_md5_get_count_setting( salt );
    if( count_log2 === false )
    {
        return hex_md5( password );
    }

    var hash = rstr_md5( salt.substring( 1 ) + password );
    do
    {
        hash = rstr_md5( hash + password );
    }
    while( --count_log2 );

    return salted_md5_hash_encode64( hash, 16 );
}

salted_md5_hash( '
.$var_password_name.', '.$var_salt_name.' );
'
;

        return
$js_code;
    }


   
/**
     * Get a random salt value
     *
     * @return string Salt for password hashing
     */
   
protected function get_random_salt()
    {
       
$count = 6;

       
$random = generate_random_key( $count );

       
$salt = $this->itoa64[ min( $count + 5, 30 ) ];
       
$salt .= $this->hash_encode64( $random, $count );

       
// Save last generated salt to know what value write in DB on user password updating:
       
$this->last_generated_salt = $salt;

        return
$salt;
    }


   
/**
     * Get setting count_log2 from salt to generate new hash
     *
     * @param string The salt that contains the setting in first char
     *
     * @return boolean|integer Containing the count_log2
     *         or false if supplied salt is incorrect
     */
   
public function get_count_setting( $salt )
    {
        if( empty(
$salt ) || strlen( $salt ) != $this->salt_length )
        {    
// Wrong salt format:
           
return false;
        }

       
$count_log2 = strpos( $this->itoa64, $salt[0] );

        if(
$count_log2 < 7 || $count_log2 > 30 )
        {    
// Not allowed value:
           
return false;
        }

        return
1 << $count_log2;
    }
}
?>