encryption my password

Started by
18 comments, last by Pedro Alves 9 years, 9 months ago
Are you saying that you want to authenticate against an existing database schema, particularly that of joomla 2.5.22? Some quick Googling indicates they may have an API to help you.

i want hash my password in client side and send to server verify a hash is the same i have in database

Is there a reason you want to do this? It isn't necessarily more secure. If you send a hash of a password, then that hashed value effectively is the "real" password. Yes, an attacker in the middle might have difficulty determining the plaintext password, but they don't need it - they can re-send the hashed value they sniff on the network and the server can't tell they don't know the real value.

Used correctly, SSL solves the problem of a Man in the Middle attack.
Advertisement

yes i want authenticate my game using the joomla 2.5.22 database

but my problem i can´t make the password to match with password it is in database

the reason is i can use the joomla to make my website

Hello

Used correctly, SSL solves the problem of a Man in the Middle attack.

Can mitigate the chances of a successful man in the middle attack.

I realize I'm being a bit pedantic, but I do feel that people should understand the potential issues that currently exist with our existing SSL implementations...

Unfortunately, in the modern SSL environment there is no real means of preventing a man in the middle attack, what with the proliferation of hacked CAs and the ability of many of our world governments being able to request wildcard certificates and such from CAs under gag orders to prevent disclosure of such issuance...

Convergence might be a solution for these issues though, if it can ever get going and get the support behind it that it needs.

yes i want authenticate my game using the joomla 2.5.22 database
but my problem i can´t make the password to match with password it is in database
the reason is i can use the joomla to make my website

Joomla appears to have an API for this, even if it doesn't, I don't really recommend necessarily linking the systems in this manner. Especially if Joomla is using MD5 or SHA1 for password hashing, as neither are cryptographic hashes. My preference, if stated, would be for either linking joomla into a separate authentication system (using an authentication plugin) or using authentication bridges.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

now joomla 2.5.22 uses now phppass

this is the code


<?php
#
# Portable PHP password hashing framework.
#
# Version 0.3 / genuine.
#
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
# the public domain.  Revised in subsequent years, still public domain.
#
# There's absolutely no warranty.
#
# The homepage URL for this framework is:
#
#	http://www.openwall.com/phpass/
#
# Please be sure to update the Version line if you edit this file in any way.
# It is suggested that you leave the main version number intact, but indicate
# your project name (after the slash) and add your own revision information.
#
# Please do not change the "private" password hashing method implemented in
# here, thereby making your hashes incompatible.  However, if you must, please
# change the hash type identifier (the "$P$") to something different.
#
# Obviously, since this code is in the public domain, the above are not
# requirements (there can be none), but merely suggestions.
#
class PasswordHash {
	var $itoa64;
	var $iteration_count_log2;
	var $portable_hashes;
	var $random_state;

	function PasswordHash($iteration_count_log2, $portable_hashes)
	{
		$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

		if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
			$iteration_count_log2 = 8;
		$this->iteration_count_log2 = $iteration_count_log2;

		$this->portable_hashes = $portable_hashes;

		$this->random_state = microtime();
		if (function_exists('getmypid'))
			$this->random_state .= getmypid();
	}

	function get_random_bytes($count)
	{
		$output = '';
		if (is_readable('/dev/urandom') &&
		    ($fh = @fopen('/dev/urandom', 'rb'))) {
			$output = fread($fh, $count);
			fclose($fh);
		}

		if (strlen($output) < $count) {
			$output = '';
			for ($i = 0; $i < $count; $i += 16) {
				$this->random_state =
				    md5(microtime() . $this->random_state);
				$output .=
				    pack('H*', md5($this->random_state));
			}
			$output = substr($output, 0, $count);
		}

		return $output;
	}

	function encode64($input, $count)
	{
		$output = '';
		$i = 0;
		do {
			$value = ord($input[$i++]);
			$output .= $this->itoa64[$value & 0x3f];
			if ($i < $count)
				$value |= ord($input[$i]) << 8;
			$output .= $this->itoa64[($value >> 6) & 0x3f];
			if ($i++ >= $count)
				break;
			if ($i < $count)
				$value |= ord($input[$i]) << 16;
			$output .= $this->itoa64[($value >> 12) & 0x3f];
			if ($i++ >= $count)
				break;
			$output .= $this->itoa64[($value >> 18) & 0x3f];
		} while ($i < $count);

		return $output;
	}

	function gensalt_private($input)
	{
		$output = '$P$';
		$output .= $this->itoa64[min($this->iteration_count_log2 +
			((PHP_VERSION >= '5') ? 5 : 3), 30)];
		$output .= $this->encode64($input, 6);

		return $output;
	}

	function crypt_private($password, $setting)
	{
		$output = '*0';
		if (substr($setting, 0, 2) == $output)
			$output = '*1';

		$id = substr($setting, 0, 3);
		# We use "$P$", phpBB3 uses "$H$" for the same thing
		if ($id != '$P$' && $id != '$H$')
			return $output;

		$count_log2 = strpos($this->itoa64, $setting[3]);
		if ($count_log2 < 7 || $count_log2 > 30)
			return $output;

		$count = 1 << $count_log2;

		$salt = substr($setting, 4, 8);
		if (strlen($salt) != 8)
			return $output;

		# We're kind of forced to use MD5 here since it's the only
		# cryptographic primitive available in all versions of PHP
		# currently in use.  To implement our own low-level crypto
		# in PHP would result in much worse performance and
		# consequently in lower iteration counts and hashes that are
		# quicker to crack (by non-PHP code).
		if (PHP_VERSION >= '5') {
			$hash = md5($salt . $password, TRUE);
			do {
				$hash = md5($hash . $password, TRUE);
			} while (--$count);
		} else {
			$hash = pack('H*', md5($salt . $password));
			do {
				$hash = pack('H*', md5($hash . $password));
			} while (--$count);
		}

		$output = substr($setting, 0, 12);
		$output .= $this->encode64($hash, 16);

		return $output;
	}

	function gensalt_extended($input)
	{
		$count_log2 = min($this->iteration_count_log2 + 8, 24);
		# This should be odd to not reveal weak DES keys, and the
		# maximum valid value is (2**24 - 1) which is odd anyway.
		$count = (1 << $count_log2) - 1;

		$output = '_';
		$output .= $this->itoa64[$count & 0x3f];
		$output .= $this->itoa64[($count >> 6) & 0x3f];
		$output .= $this->itoa64[($count >> 12) & 0x3f];
		$output .= $this->itoa64[($count >> 18) & 0x3f];

		$output .= $this->encode64($input, 3);

		return $output;
	}

	function gensalt_blowfish($input)
	{
		# This one needs to use a different order of characters and a
		# different encoding scheme from the one in encode64() above.
		# We care because the last character in our encoded string will
		# only represent 2 bits.  While two known implementations of
		# bcrypt will happily accept and correct a salt string which
		# has the 4 unused bits set to non-zero, we do not want to take
		# chances and we also do not want to waste an additional byte
		# of entropy.
		$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

		$output = '$2a$';
		$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
		$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
		$output .= '$';

		$i = 0;
		do {
			$c1 = ord($input[$i++]);
			$output .= $itoa64[$c1 >> 2];
			$c1 = ($c1 & 0x03) << 4;
			if ($i >= 16) {
				$output .= $itoa64[$c1];
				break;
			}

			$c2 = ord($input[$i++]);
			$c1 |= $c2 >> 4;
			$output .= $itoa64[$c1];
			$c1 = ($c2 & 0x0f) << 2;

			$c2 = ord($input[$i++]);
			$c1 |= $c2 >> 6;
			$output .= $itoa64[$c1];
			$output .= $itoa64[$c2 & 0x3f];
		} while (1);

		return $output;
	}

	function HashPassword($password)
	{
		$random = '';

		if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
			$random = $this->get_random_bytes(16);
			$hash =
			    crypt($password, $this->gensalt_blowfish($random));
			if (strlen($hash) == 60)
				return $hash;
		}

		if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
			if (strlen($random) < 3)
				$random = $this->get_random_bytes(3);
			$hash =
			    crypt($password, $this->gensalt_extended($random));
			if (strlen($hash) == 20)
				return $hash;
		}

		if (strlen($random) < 6)
			$random = $this->get_random_bytes(6);
		$hash =
		    $this->crypt_private($password,
		    $this->gensalt_private($random));
		if (strlen($hash) == 34)
			return $hash;

		# Returning '*' on error is safe here, but would _not_ be safe
		# in a crypt(3)-like function used _both_ for generating new
		# hashes and for validating passwords against existing hashes.
		return '*';
	}

	function CheckPassword($password, $stored_hash)
	{
		$hash = $this->crypt_private($password, $stored_hash);
		if ($hash[0] == '*')
			$hash = crypt($password, $stored_hash);

		return $hash == $stored_hash;
	}
}

?>

Hello

Can mitigate the chances of a successful man in the middle attack.

I realize I'm being a bit pedantic, but I do feel that people should understand the potential issues that currently exist with our existing SSL implementations...

Unfortunately, in the modern SSL environment there is no real means of preventing a man in the middle attack, what with the proliferation of hacked CAs and the ability of many of our world governments being able to request wildcard certificates and such from CAs under gag orders to prevent disclosure of such issuance...

While I'm not disagreeing with you, generally attackers of such sophistication and resources are not part of the threat model for most developers here. But yes I worded that a bit too strongly. I believe an earlier draft of the post used the word "infeasible", but it was lost in a re-write.

@Landi20, you still haven't explained what is or isn't happening. You've posted code, and you have posted what appears to be two hashed passwords, one of which presumably is in the Joomla database and another is generated from your C# code somehow. Did you write the C# code yourself? If not, where did you find it? Can you post a unit test or short sample program that shows how you are using this code? Be very clear on which plain text passwords you are using and which hashes they correspond with.

but i can´t have the same password everytime change when send to the server

This indicates that you're probably not using the correct method. If the hashed password is not the same, then you're probably using the method for saving new passwords, not checking existing ones.

To check an existing password on the client, the client would have to know the salt, which you should not be sending to the client (you cannot trust that it even is a legitimate user). If you want to use the same database as Joomla, you'll have to conform to their mechanism, which is that the server must receive the plaintext password (delivered securely using SSL) and the server then validates this.

i not write the code i gonna post the code with text example

i make some changes


 private string itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
        /// <summary>
        /// Compares the password string given with the hash retrieved from your database.
        /// </summary>
        /// <param name="password">Plaintext password.</param>
        /// <param name="hash">Hash from a SQL database</param>
        /// <returns>True if the password is correct, False otherwise.</returns>
        public bool phpbbCheckHash(string password, string hash)
        {
            if (hash.Length == 34) return (hashCryptPrivate(ASCIIEncoding.ASCII.GetBytes(password), hash, itoa64) == hash);
            return false;
        }
 
        /// <summary>
        /// This function will return the resulting hash from the password string you specify.
        /// </summary>
        /// <param name="password">String to hash.</param>
        /// <returns>Encrypted hash.</returns>
        /// <remarks>
        /// Although this will return the md5 for an older password, I have not added
        /// support for older passwords, so they will not work with this class unless
        /// I or someone else updates it.
        /// </remarks>
        public string phpbb_hash(string password)
        {
            // Generate a random string from a random number with the length of 6.
            // You could use a static string instead, doesn't matter. E.g.
            // byte[] random = ASCIIEncoding.ASCII.GetBytes("abc123");
            byte[] random = ASCIIEncoding.ASCII.GetBytes(new Random().Next(100000, 999999).ToString());
 
            string hash = hashCryptPrivate(ASCIIEncoding.ASCII.GetBytes(password), hashGensaltPrivate(random, itoa64), itoa64);
 
            if (hash.Length == 34) return hash;
 
            return sMD5(password);
        }
 
        /// <summary>
        /// The workhorse that encrypts your hash.
        /// </summary>
        /// <param name="password">String to be encrypted. Use: ASCIIEncoding.ASCII.GetBytes();</param>
        /// <param name="genSalt">Generated salt.</param>
        /// <param name="itoa64">The itoa64 string.</param>
        /// <returns>The encrypted hash ready to be compared.</returns>
        /// <remarks>
        /// password:  Saves conversion inside the function, lazy coding really.
        /// genSalt:   Returns from hashGensaltPrivate(random, itoa64);
        /// return:    Compare with phpbbCheckHash(password, hash)
        /// </remarks>
        private string hashCryptPrivate(byte[] password, string genSalt, string itoa64)
        {
            string output = "*";
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            if (!genSalt.StartsWith("$P$")) return output;
            //   $count_log2 = strpos($itoa64, $setting[3]);
            int count_log2 = itoa64.IndexOf(genSalt[3]);
            if (count_log2 < 7 || count_log2 > 30) return output;
 
            int count = 1 << count_log2;
            byte[] salt = ASCIIEncoding.ASCII.GetBytes(genSalt.Substring(4, 8));
 
            if (salt.Length != 8) return output;
 
            byte[] hash = md5.ComputeHash(Combine(salt, password));
 
            do
            {
                hash = md5.ComputeHash(Combine(hash, password));
            } while (count-- > 1);
 
            output = genSalt.Substring(0, 12);
            output += hashEncode64(hash, 16, itoa64);
 
            return output;
        }
 
        /// <summary>
        /// Private function to concat byte arrays.
        /// </summary>
        /// <param name="b1">Source array.</param>
        /// <param name="b2">Array to add to the source array.</param>
        /// <returns>Combined byte array.</returns>
        private byte[] Combine(byte[] b1, byte[] b2)
        {
            byte[] retVal = new byte[b1.Length + b2.Length];
            Array.Copy(b1, 0, retVal, 0, b1.Length);
            Array.Copy(b2, 0, retVal, b1.Length, b2.Length);
            return retVal;
        }
 
        /// <summary>
        /// Encode the hash.
        /// </summary>
        /// <param name="input">The hash to encode.</param>
        /// <param name="count">[This parameter needs documentation].</param>
        /// <param name="itoa64">The itoa64 string.</param>
        /// <returns>Encoded hash.</returns>
        private string hashEncode64(byte[] input, int count, string itoa64)
        {
            string output = "";
            int i = 0; int value = 0;
 
            do
            {
                value = input[i++];
                output += itoa64[value & 0x3f];
 
                if (i < count) value |= input[i] << 8;
                output += itoa64[(value >> 6) & 0x3f];
                if (i++ >= count)
                    break;
 
                if (i < count) value |= input[i] << 16;
                output += itoa64[(value >> 12) & 0x3f];
                if (i++ >= count)
                    break;
 
                output += itoa64[(value >> 18) & 0x3f];
 
            } while (i < count);
 
            return output;
        }
 
        /// <summary>
        /// Generate salt for hash generation.
        /// </summary>
        /// <param name="input">Any random information.</param>
        /// <param name="itoa64">The itoa64 string.</param>
        /// <returns>Generated salt string</returns>
        private string hashGensaltPrivate(byte[] input, string itoa64)
        {
            int iteration_count_log2 = 6;
 
            string output = "$P$";
            output += itoa64[Math.Min(iteration_count_log2 + 5, 30)];
            output += hashEncode64(input, 6, itoa64);
 
            return output;
        }
 
        /// <summary>
        /// Returns a hexadecimal string representation for the encrypted MD5 parameter.
        /// </summary>
        /// <param name="password">String to be encrypted.</param>
        /// <returns>String</returns>
        private string sMD5(string password) { return sMD5(password, false); }
 
        /// <summary>
        /// Returns a hexadecimal string representation for the encrypted MD5 parameter.
        /// </summary>
        /// <param name="password">String to be encrypted.</param>
        /// <param name="raw">Whether or not to produce a raw string.</param>
        /// <returns>String</returns>
        private string sMD5(string password, bool raw)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            if (raw) return Encoding.ASCII.GetString(md5.ComputeHash(Encoding.ASCII.GetBytes(password)));
            else return BitConverter.ToString(md5.ComputeHash(Encoding.ASCII.GetBytes(password))).Replace("-", "");
        }
    
   
     }

my program with example


   void btnApply_Click(object sender, Controls.EventArgs e)
    {
       String pass; 
        Login login = new Login();
       string usernane = "maria";
       string password = "123456";
    pass = login.phpbb_hash(password);
   System.Console.WriteLine(pass);
}

expecte $P$DzZ6dPRg/zHF6G3vRHgskT1.FwoX9k/

result $P$9tIHClUHBDhxbsipTwoMCKWzvDZSTP1

only can work if send a password with not incryptation and use this function in class login phpbbCheckHash(string password, string hash)

but is not i want i want send a password incrypted to the server and confirm if the password is correct your not

Hello

It appears you don't understand how this works. You're calling the method to save a new password. The first thing it does is generate some random bytes, to be used for the salt.

In order the generate the value in the database, you have to lookup the database first and split the saved string into the salt and hashed password. In order for the client to do this, it would first have to send the username to the server, and the server would have to send the salt for that user (if it exists). This means that an unauthenticated client can essentially query the server for usernames and salts, which would generally be considered insecure.

Do you understand how Joomla is authenticating? Do you understand salting? Do you understand the threat it mitigates against, and how? Why do you want the client to hash the password? Is there a reason you don't want to use SSL? What part of the explanations and suggestions you've got so far are you having difficulty with?

i understante a little of joomla authenticating and salt and i understante a threat i gonna be i want hash the password in cliente becouse i think is more secure send a password incrypted

no i dont have any reason to don´t use ssl i say in post i maybe use the ssl to connect to the server

my difficulty in incryptation and sockets

i never programed using sockets and i learning to use sockets

my main programmed language in java

Hello

It is spelled "encrypted" and "client". I understand you might have some difficulty with English, but take particular care with technical terminology as deviating too far can make it incredible difficult to read and understand your posts. Try using a spell-checker configured to English if you're not doing so already.

Right now there is no encryption, just hashing. These are very different things, even though the end result appears to be scrambled data. Encryption is reversible, that is the server can tell exactly what the client originally sent it. Hashing is not reversible, as multiple inputs can map to the same output (though for passwords, some inputs are more likely than others). An important security property of proper encryption is that the scrambled data is different each session even if the same data is exchanged.

If you hash on the client side, and send that hashed value over an unencrypted link, then an attacker only has to sniff and replay the hashed value to authenticate. I've mentioned this earlier in the thread.

If you use SSL, then the network connection is actually encrypted, which renders it infeasible for an attacker to merely sniff the network and get access to the credentials.

So using SSL is the solution, and hashing on the client is not the solution. Securing such a system is a well known, solved problem. You don't need to design this yourself. It is unfortunately all too easy to design a system that users encryption and hashing but actually remains vulnerable to all sorts of inventive attacks. Use the tried and tested best practise instead.

ok thanks

Hello

This topic is closed to new replies.

Advertisement