Search code examples
validationmagentoauthenticationmd5salt-cryptography

Has the hash password function changed in magento? If so, to what?


I am using magento version 1.9.0.1.

For switching to magento purposes I need to create a login function for customers outside the magento framework.

I have looked up the method magento uses to hash and validate passwords, but the method doesn't seem to work anymore.

Below the code I use to validate a user login outside magento. This code is just to try proof of concept and is not being used in a live environment for obvious reasons :).

function checkPassword($entity,$passwordInput){
    $query = mysql_query("SELECT value FROM customer_entity_varchar WHERE entity_id = '$entity' AND attribute_id = '12' LIMIT 1");
    $fetch = mysql_fetch_object($query);
    $fetch_data = explode(':',$fetch->value);
    $hashed_password = $fetch_data['0'];
    $salt = $fetch_data['1'];

    $hashInput = md5($passwordInput . $salt);
    if($hashInput == $hashed_password){
        return 'Success';
    }
    else{
        return 'Failure';
    }
}

$entity is the entity_id passed after email validation,

$passwordInput is the password entered in the login form.

It returns Failure. Which I'm not surprised about because when I return $hashInput and compare it with $hashed_password it's not the same.

Has the way Magento hashes passwords been changed? Or is there a mistake in my code?


Solution

  • If you check in \app\code\core\Mage\Customer\Model\Customer.php you can find something like this (near line 430) :

    /**
     * Encrypt password
     *
     * @param   string $password
     * @return  string
     */
    public function encryptPassword($password)
    {
        return Mage::helper('core')->encrypt($password);
    }
    

    The helper('core') is \app\code\core\Mage\Core\Helper\Data.php

    In \app\code\core\Mage\Core\Helper\Data.php, you find :

    /**
     * Encrypt data using application key
     *
     * @param   string $data
     * @return  string
     */
    public function encrypt($data)
    {
        if (!Mage::isInstalled()) {
            return $data;
        }
        return $this->getEncryptor()->encrypt($data);
    }
    

    and getEncryptor() function is :

    /**
     * @return Mage_Core_Model_Encryption
     */
    public function getEncryptor()
    {
        if ($this->_encryptor === null) {
            $encryptionModel = (string)Mage::getConfig()->getNode(self::XML_PATH_ENCRYPTION_MODEL);
            if ($encryptionModel) {
                $this->_encryptor = new $encryptionModel;
            } else {
                $this->_encryptor = Mage::getModel('core/encryption');
            }
    
            $this->_encryptor->setHelper($this);
        }
        return $this->_encryptor;
    }
    

    $this->_encryptor is in \app\code\core\Mage\Core\Model\Encryption.php and in this file you can find :

    /**
     * Encrypt a string
     *
     * @param string $data
     * @return string
     */
    public function encrypt($data)
    {
        return base64_encode($this->_getCrypt()->encrypt((string)$data));
    }
    

    and

    /**
     * Instantiate crypt model
     *
     * @param string $key
     * @return Varien_Crypt_Mcrypt
     */
    protected function _getCrypt($key = null)
    {
        if (!$this->_crypt) {
            if (null === $key) {
                $key = (string)Mage::getConfig()->getNode('global/crypt/key');
            }
            $this->_crypt = Varien_Crypt::factory()->init($key);
        }
        return $this->_crypt;
    }
    

    (string)Mage::getConfig()->getNode('global/crypt/key'); is in /app/etc/local.xml file.

    Your variable $hashed_password pass by this last method.

    Your variable $hashInput also pass there ?


    So, you can change in your checkPassword() function :

    $hashInput = md5($passwordInput . $salt);
    

    to

    $hashInput = encryptPassword($passwordInput);
    

    Thereby, $hashInput and $hashed_password will follow the same way.