34

I need to access the joomla user table jos_users for login checking from external php script [codeignitor].

joomla storing password like this

4e9e4bcc5752d6f939aedb42408fd3aa:0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT

Looks like this is not the normal MD5 ,so i cannot use md5(password) .

what is the possible way to create the password ?

Thank you.

Red
  • 6,230
  • 12
  • 65
  • 112
  • 1
    deep question :) and if you still think that md5 is the normal way to store passwords you might want to do a little more research on that – mishu May 03 '12 at 09:00
  • 4
    Just a FYI, MD5 should NEVER be used for hashing passwords. Ever. Especially without a salt like in your example. – tangrs May 03 '12 at 09:01
  • Thanks for the info ; But here i am not about to generate a password field. – Red May 03 '12 at 10:09
  • Why don't you explain what it is exactly that you are trying to do. Is your purpose to reset or create a password from an external script? At first that was what it sounded like but now it sounds like you want something different. Are you trying to login? – Elin Dec 04 '12 at 12:42

9 Answers9

63

Joomla passwords are MD5 hashed, but the passwords are salted before being hashed. They are stored in the database as {hash}:{salt} this salt is a random string 32 characters in length.

So to create a new password hash you would do md5($password.$salt)

EDIT

Okay so for checking a password, say a user myguy enters the password mypassword, you would retrieve the row from the database that has username myguy.

In this row you'll find a password say 4e9e4bcc5752d6f939aedb42408fd3aa:0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT. You split up the password hash and the salt:

$hashparts = preg_split (':' , $dbpassword);
echo $hashparts[0]; //this is the hash  4e9e4bcc5752d6f939aedb42408fd3aa
echo $hashparts[1]; //this is the salt  0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT

now calculate the hash using this salt and the password myguy entered

$userhash = md5($userpassword.$hashparts[1]); // This would be 'mypassword' and the salt used in the original hash

Now if this $userhash and $hashparts[0] are identical the user has entered the correct password.

klennepette
  • 3,176
  • 22
  • 23
  • 3
    For an existing password just take the string after the `:` that's the salt. For creating a new password salt just generate a random string. As Er. Anurag Jain's stated in his answer you can easily do this with `JUserHelper::genRandomPassword(32)` – klennepette May 03 '12 at 10:15
  • Sorry ,but still i cant find the answer to the question , assume that user have a pass `hello` ,but how i know that random number ? its generated & stored in db by JOOMLA .. – Red May 03 '12 at 10:39
  • 1
    @DileepDil See my edit for an explanation how to check the password. – klennepette May 03 '12 at 13:48
  • Did you use real data in this example? I got md5(mypassword0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT) == 0ac1a27af8bc4f99edd278dde1fbd18b – noisy Jul 30 '13 at 10:54
  • 1
    @noisy I did not use real data no. The hash and salt is from the question and I just made up the password, they won't match. – klennepette Jul 30 '13 at 12:00
  • I think last sentence is wrong, at the end if `$userhash` and `$hashparts` are identical the user entered the correct password. You could check this directly in database, just in case anybody need it: `select * from ?_users where concat(md5(concat($your_password,substr(password,34))),substr(password,33)) = password ` – chavocarlos Sep 04 '13 at 15:53
  • 1426d09a369996aeb0bb35a7af341ff5-->userhash $P$DgfK3C89FAL -->orginalhash is the output its not the same even if the input passqord is correct. – Amit May 03 '14 at 07:42
  • when i do echo $hash = md5('mypassword0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT') . ':0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT'; it returns 0ac1a27af8bc4f99edd278dde1fbd18b:0vURRbyY8Ea0tlvnTFn7xcKpjTFyn0YT – Adnan Nov 15 '14 at 09:28
  • That no longer works. Joomla 3 has a different way to store passwords and it seems nobody knows about it. I need to check the user's entered password with the one saved in the Joomla database table, and I CAN'T do it in PHP. – nemesys May 09 '15 at 18:52
22

From joomla Forum, that's what happen behind:

A. Generate a password
B. Generate a string with 32 random characters
C. Concatenate Password (Step A) and RandomString (Step B)
D. Take md5(Result of Step C)
E. store Step D Result : Step B Result

Example:

Generate a password - Let 'testing'
Generate a string of 32 random characters - 'aNs1L5PajsIscupUskaNdPenustelsPe'
Concatenate Password and random string - testingaNs1L5PajsIscupUskaNdPenustelsPe
md5(Step C Result) - 5cf56p85sf15lpyf30c3fd19819p58ly
store step d:step B - 5cf56p85sf15lpyf30c3fd19819p58ly:aNs1L5PajsIscupUskaNdPenustelsPe

You can find code in Joomla like

$salt = JUserHelper::genRandomPassword(32);
$crypt = JUserHelper::getCryptedPassword("testing", $salt);
$password = $crypt . ':' . $salt;

Or We can Say

password DB field = md5(password + salt) + ":" + salt 

Where salt is random 32 char string.

thanks

Er. Anurag Jain
  • 1,780
  • 1
  • 11
  • 19
  • I am not about to register a new user ,i need to get the current string on the password field.So that i can match bother user given password and the password on the password field. – Red May 03 '12 at 10:06
  • 1
    md5 is a one way hash, which means you can only encrypt it but not reverse the decryption, its not possbile to do dycription You can do a thing that first fetch 32 car random string from db password , and with help of that security key create joomla type password from input password and match both... – Er. Anurag Jain May 03 '12 at 11:23
  • how can i fetch the random string from the password ? how its gonna posible ? – Red May 03 '12 at 17:33
  • hi joomla db password format is md5(password + salt) : salt where salt is a secret key so you can explode secret key from given password using `:` keyword...and then use that with your password to generate joomla type password and then match both password (generated by yoourself and db password) ... thanks – Er. Anurag Jain May 04 '12 at 04:29
  • 1
    This same question to, you. Did you use real data in this example? I got md5(testingaNs1L5PajsIscupUskaNdPenustelsPe) == 6e05e46fcc516a612a4afa9b9b7827c7 – noisy Jul 30 '13 at 10:55
  • No it's example data..not real data..but joomla password encryprion functionality working live given above.. – Er. Anurag Jain Jul 31 '13 at 06:47
5

In joomla standard you can create password using the following way

                     jimport('joomla.user.helper');
             $salt = JUserHelper::genRandomPassword(32);
             $crypt = JUserHelper::getCryptedPassword($password_choose, $salt);
             $password = $crypt.':'.$salt;

you mention that you are accessing from external file(or programs) then if you have joomla installation on other side you can access it from outside the joomla structure.

using joomla default frame work like this

define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(__FILE__) );//this is when we are in the root
define( 'DS', DIRECTORY_SEPARATOR );

require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );

$mainframe =& JFactory::getApplication('site');
$mainframe->initialise();
Jobin
  • 8,238
  • 1
  • 33
  • 52
  • http://stackoverflow.com/questions/10409432/access-joomla-session-in-php-codeigniter - this question is still unanswered :) – Red May 03 '12 at 10:07
3

I couldn't use preg_split but explode works well.

$hashparts = explode (':' , $dbpassword);
Pete
  • 57,112
  • 28
  • 117
  • 166
jayadevkv
  • 384
  • 3
  • 16
  • Just to note that in some cases, salts can contain any set of characters and that could also include a colon `:` symbol. Using `explode` in this way will create an array with `n+1` number of items where `n` equals number of colons. The `explode` function accepts a third argument which limits how many times to split the string by. Here, we should probably set that to 2. `explode(':', $dbpassword, 2);` – nxasdf Apr 10 '22 at 01:32
2

From the joomla source file libraries/joomla/crypt/password/simple.php there are multiple ways they get stored, and some do not have a ':' character.

    switch ($type)
    {
        case '$2a$':
        case JCryptPassword::BLOWFISH:
            if (JCrypt::hasStrongPasswordSupport())
            {
                $type = '$2y$';
            }
            else
            {
                $type = '$2a$';
            }

            $salt = $type . str_pad($this->cost, 2, '0', STR_PAD_LEFT) . '$' . $this->getSalt(22);

            return crypt($password, $salt);

        case JCryptPassword::MD5:
            $salt = $this->getSalt(12);

            $salt = '$1$' . $salt;

            return crypt($password, $salt);

        case JCryptPassword::JOOMLA:
            $salt = $this->getSalt(32);

            return md5($password . $salt) . ':' . $salt;


    }
}
Sam Adamsh
  • 3,331
  • 8
  • 32
  • 53
2

Joomla! uses PhPass.

root/libraries/phpass/PasswordHash.php

have a look here. you will see here how the password is generating.

The $2y is the default (and preferred) prefix on bcrypt hashes. As for code, you'll want to look inside JUserHelper's hashPassword and verifyPassword methods to see how Joomla's working with things right now.


Some Referances -

https://github.com/joomla/joomla-cms/blob/3.4.1/libraries/joomla/user/helper.php#L296-L387

https://docs.joomla.org/API15:JUserHelper/getCryptedPassword

https://docs.joomla.org/API15:JUserHelper/getSalt

Check the links, I hope you it will helpful :)

Community
  • 1
  • 1
Joomler
  • 2,610
  • 3
  • 30
  • 37
0

Joomla "understands" the passwords with "normal" md5.

What I've done in the past (to test a user's login), was to save the original password, encrypt a new one in md5, replace it in the database, test it with the browser (and it works) and when I was done, paste the original password in the database.

jackJoe
  • 11,078
  • 8
  • 49
  • 64
0
<?php
$r = bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM));
$p = 'the_password';

$s = $p . $r;
$m = md5($s);

$out = $m . ':' . $r;
echo $out;

Len 16 because bin2hex doubles the character size, since 1 byte becomes 2 bytes

-2

If you just use md5($password); it'll work, try it. Joomla has a mechanism and it can work with multiple types of passwords (including, as of late, strong passwords). You don't have to worry about the part after the colon. Just use md5($password) and it'll definitely work.

By the way, this'll also work on Joomla 3.x.

itoctopus
  • 4,133
  • 4
  • 32
  • 44