Hi all,

I am creating a new login form, different from the default login, but when i try to connect to the database. it said password is not correct.. I just realised that password is encrypted. but i dont know what kind of algorithm it uses.

I am using joomla and also use joomla default user's table for the password. I checked on the file and found that it use algorithm like this :

$crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
            $array['password'] = $crypt.':'.$salt;

Anyone know what is the syntax for this algorithm? I tried using this but its not working :

$pass     = (md5($_POST['password']).":".$salt);

Please help for the right syntax....

Leo

Dani AI

Generated

Short answer for : you do not "decrypt" Joomla passwords. The value in the users table represents a digest (and sometimes a salt or a format marker). To authenticate you must reproduce exactly the same hashing process Joomla used for that stored value, then compare the results — do not try to match by building a SQL WHERE password='…' string.

How to approach (high level):

  • Retrieve the user row by username, read the password column and inspect its format. Some values have explicit markers (for example a leading tag like {SHA}/{MD5}), others use crypt-style strings ($apr1$ or $2$), and the older default salted MD5 form places the salt after a colon.
  • Decide which algorithm is indicated, recreate the digest from the password supplied by the user using the same algorithm and salt, and compare the computed digest to the stored one. If you want to be certain, use the exact JUserHelper routines in your Joomla installation as your reference (as suggested) rather than guessing.

Troubleshooting and practical tips:

  • Hashes are one-way — you cannot reverse them, only re-hash candidate passwords and compare (as pointed out).
  • Watch for trimming/encoding issues (hidden whitespace, different character encodings) and for missing PHP extensions required by certain schemes (mhash/crypt).
  • Use a timing-safe comparison when comparing digests (for example hash_equals if available).
  • Prefer calling Joomla’s authentication layer or its helper functions instead of reimplementing hashing logic in multiple places. Finally, MD5-based storage is weak by modern standards — plan a migration to stronger hashing (bcrypt / PHP password_hash) when you can.

Recommended Answers

All 9 Replies

I don't know, why you can't use simple sha1??

$password=$_POST['wbst_pass'];
$passd_enc=sha1($password);
$passd_enc=mysql_real_escape_string($passd_enc);
$passd_enc=stripslashes($passd_enc);

As far as i know, Joomla uses md5 salt hash algorithm.. since i am using the default table from joomla for the user aka (jos_users table), SHA1 will not authenticate the password, I need to know the right syntax when i retrieve field from the table where password = '$pass' ;

Anyone know the syntax?

ok in php is like this

$password=md5($_POST['password']).$salt;

$salt="1234jggkgjkgjk";

Sorry dany12, but i tried that one, and still get no result.

Here is one of the encrypted password which i took from phpmyadmin :

3ea171b82a475be10c52f0973e7ed06f:fIqDmhAwLWZk9wfWfzenAVFLrskq24fx

Is there anyone who can decrypt this? and what is the php syntax...

Thanks...

This string is 65 characters long, if you use var_dump(explode(':',$string)); you will see two strings of 32 characters each, so probably these are two md5 hashes, and you can't decrypt an hash, you can only try to find a collision, i.e. a string that creates the same hash. In order to create an hash you can use sha1() or md5(), as suggested before by the others.

md5: http://php.net/manual/en/function.md5.php

The only way to get them to work together is to copy exactly how joomla hashes their password. I would say, find the JUserHelper class and look how the getCryptedPassword function is working.

I found the getCryptedpassword function

function getCryptedPassword($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)
    {
        // Get the salt to use.
        $salt = JUserHelper::getSalt($encryption, $salt, $plaintext);

        // Encrypt the password.
        switch ($encryption)
        {
            case 'plain' :
                return $plaintext;

            case 'sha' :
                $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext));
                return ($show_encrypt) ? '{SHA}'.$encrypted : $encrypted;

            case 'crypt' :
            case 'crypt-des' :
            case 'crypt-md5' :
            case 'crypt-blowfish' :
                return ($show_encrypt ? '{crypt}' : '').crypt($plaintext, $salt);

            case 'md5-base64' :
                $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext));
                return ($show_encrypt) ? '{MD5}'.$encrypted : $encrypted;

            case 'ssha' :
                $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext.$salt).$salt);
                return ($show_encrypt) ? '{SSHA}'.$encrypted : $encrypted;

            case 'smd5' :
                $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext.$salt).$salt);
                return ($show_encrypt) ? '{SMD5}'.$encrypted : $encrypted;

            case 'aprmd5' :
                $length = strlen($plaintext);
                $context = $plaintext.'$apr1$'.$salt;
                $binary = JUserHelper::_bin(md5($plaintext.$salt.$plaintext));

                for ($i = $length; $i > 0; $i -= 16) {
                    $context .= substr($binary, 0, ($i > 16 ? 16 : $i));
                }
                for ($i = $length; $i > 0; $i >>= 1) {
                    $context .= ($i & 1) ? chr(0) : $plaintext[0];
                }

                $binary = JUserHelper::_bin(md5($context));

                for ($i = 0; $i < 1000; $i ++) {
                    $new = ($i & 1) ? $plaintext : substr($binary, 0, 16);
                    if ($i % 3) {
                        $new .= $salt;
                    }
                    if ($i % 7) {
                        $new .= $plaintext;
                    }
                    $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext;
                    $binary = JUserHelper::_bin(md5($new));
                }

                $p = array ();
                for ($i = 0; $i < 5; $i ++) {
                    $k = $i +6;
                    $j = $i +12;
                    if ($j == 16) {
                        $j = 5;
                    }
                    $p[] = JUserHelper::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5);
                }

                return '$apr1$'.$salt.'$'.implode('', $p).JUserHelper::_toAPRMD5(ord($binary[11]), 3);

            case 'md5-hex' :
            default :
                $encrypted = ($salt) ? md5($plaintext.$salt) : md5($plaintext);
                return ($show_encrypt) ? '{MD5}'.$encrypted : $encrypted;
        }
    }

But there is also GetSalt function

function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '')
    {
        // Encrypt the password.
        switch ($encryption)
        {
            case 'crypt' :
            case 'crypt-des' :
                if ($seed) {
                    return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2);
                } else {
                    return substr(md5(mt_rand()), 0, 2);
                }
                break;

            case 'crypt-md5' :
                if ($seed) {
                    return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12);
                } else {
                    return '$1$'.substr(md5(mt_rand()), 0, 8).'$';
                }
                break;

            case 'crypt-blowfish' :
                if ($seed) {
                    return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16);
                } else {
                    return '$2$'.substr(md5(mt_rand()), 0, 12).'$';
                }
                break;

            case 'ssha' :
                if ($seed) {
                    return substr(preg_replace('|^{SSHA}|', '', $seed), -20);
                } else {
                    return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
                }
                break;

            case 'smd5' :
                if ($seed) {
                    return substr(preg_replace('|^{SMD5}|', '', $seed), -16);
                } else {
                    return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
                }
                break;

            case 'aprmd5' :
                /* 64 characters that are valid for APRMD5 passwords. */
                $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

                if ($seed) {
                    return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8);
                } else {
                    $salt = '';
                    for ($i = 0; $i < 8; $i ++) {
                        $salt .= $APRMD5 {
                            rand(0, 63)
                            };
                    }
                    return $salt;
                }
                break;

            default :
                $salt = '';
                if ($seed) {
                    $salt = $seed;
                }
                return $salt;
                break;
        }
    }

but still i got confused using the right syntax for displaying data where password = '$pass';
anyone can gimme example??/

Thanks

great kkeith29, this is what I was looking for.. I will try doing the code again :).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.