Welcome!

Join our community of MMORPG enthusiasts and private server developers! By registering, you'll gain access to in-depth discussions on source codes, binaries, and the latest developments in MMORPG server files. Collaborate with like-minded individuals, explore tutorials, and share insights on building and optimizing private servers. Join us today and unlock the full potential of MMORPG server development!

Join Today!

Check password for login

Joined
Feb 13, 2009
Messages
3,303
Reaction score
651
Location
Belgium
Hello! I need an expert for PHP :P:
Well I started to write a new gm panel (and an user panel also), but I stuck on the encrypt method used by perfect world for the password...

Check my code and tell me what is wrong...
PHP:
// Perfect World encrypt password method
$encrypted_Password="0x".md5($Login.$Password);

$sql="SELECT * FROM users WHERE name='$Login' and passwd='$encrypted_Password'";
$result=mysql_query($sql);

But when I use a basic md5 encrypted password it works perfectly and I can login on my panel... But not in perfect world because it use the first method for the password...
PHP:
// Normal encrypt password method
$encrypted_Password=md5($Password);

$sql="SELECT * FROM users WHERE name='$Login' and passwd3='$encrypted_Password'";
$result=mysql_query($sql);

Thx in advance for future replies :P:
 
You are over complicating things...
PHP:
// Perfect World encrypt password method
$encrypted_Password="0x".md5($_POST['login'].$_POST['password']);

$sql="SELECT * FROM users WHERE name='".mysql_real_escape_string($_POST['login')."' and passwd='$encrypted_Password'";
$result=mysql_query($sql);

Assuming the form sends as a POST and username is "login" on the form and the password is "password"

Oh btw, I'm guessing you don't know that $Login.$Password basically means it mashes those two strings together (for example if Login was "User1" and the password was "password" it'd just be a string "User1password")
 
Your perfect world encrypt method is wrong, you should first use "strtolower" on the login.

Also to do sql query you should use sprintf and mysql_real_escape_string. Example:
Code:
$sql = sprintf('SELECT * FROM users WHERE name="%s" and passwd="%s"', mysql_real_escape_string($login), $passwd);

Otherwise I could just login with "romulan'#" :p
 
Your perfect world encrypt method is wrong, you should first use "strtolower" on the login.

Also to do sql query you should use sprintf and mysql_real_escape_string. Example:
Code:
$sql = sprintf('SELECT * FROM users WHERE name="%s" and passwd="%s"', mysql_real_escape_string($login), $passwd);

Otherwise I could just login with "romulan'#" :p

mysql real escape string not work on php last update.. use this

Code:
function romulan_string($str)
{
	$len=strlen($str);
	$escapeCount=0;
	$targetString='';
	for($offset=0;$offset<$len;$offset++)
	{
		switch($c=$str{$offset})
		{
			case "'":
				if($escapeCount % 2 == 0) $targetString.="\\";
				$escapeCount=0;
				$targetString.=$c;
				break;
			case '"':
				if($escapeCount % 2 == 0) $targetString.="\\";
				$escapeCount=0;
				$targetString.=$c;
				break;
			case '\\':
				$escapeCount++;
				$targetString.=$c;
				break;
			default:
				$escapeCount=0;
				$targetString.=$c;
		}
	}
	return $targetString;
}
?> 
$sql = sprintf('SELECT * FROM users WHERE name="%s" and passwd="%s"', romulan_string($login), $passwd);
 
If mysql_* doesn't work properly you should use which is faster and more up to date (see for examples)

@das7002 how does that even link? the encryption method which PW uses is:
Code:
md5(strtolower($login).$pass);
it makes the login case insensitive and is a common practice. If you don't do it login will fail when you have upercase in it, i.e. "UserName" will fail while it works in game.

My comment about "romulan'#" was referring to the lack of escaping. The sql request would become:
Code:
SELECT * FROM users WHERE name='romulan'#' and passwd='stuff'
effectively logging you in regardless of password, this has nothing to do with strtolower.
 
  • Like
Reactions: 343
// Perfect World encrypt password method
$encrypted_Password = $Login.$Password;
$encrypted_Password = md5($encrypted_Password);
$encrypted_Password = "0x".$encrypted_Password;

$sql="SELECT * FROM users WHERE name='$Login' and passwd='$encrypted_Password'";
$result=mysql_query($sql);

Try that, and please people don't crucify me for not adding strtolower.
 
common practice. If you don't do it login will fail when you have upercase in it, i.e. "UserName" will fail while it works in game.

I know what it does... and it is not as common of a practice as you seem to imply. Anywhere that requires security doesn't do that, everywhere that tries to prevent ID10T errors do.

PW's salt for the password is idiotic and I don't really understand the reasoning behind it, if the database gets stolen you have a known part of what created the hash which was intended to make it more difficult to figure out...
 
Finaly, I did another way... The "passwd2" in users table is not used by the pwserver. So I decided to changed the register script a little bit. When a player do an account it creates the same password both for the website and the game but encrypted differently in the two column "passwd" and "passwd2". And in the change password script, it will change the password in the two column.

Ding ding! Problem solved! :P:
 
Check your register.php its 90% from there:
Code:
	$Login = StrToLower($_POST['login']);
	$Passwd = $_POST['passwd'];
	$Password = base64_encode(md5($Login.$Passwd, true));
	$Query = MySQL_Query("select * from `users` WHERE `name`='$Login' AND `passwd`='$Password' ");
 
I know what it does... and it is not as common of a practice as you seem to imply. Anywhere that requires security doesn't do that, everywhere that tries to prevent ID10T errors do.

PW's salt for the password is idiotic and I don't really understand the reasoning behind it, if the database gets stolen you have a known part of what created the hash which was intended to make it more difficult to figure out...
It's actually really common because in most case you do not want to consider the users "das7002", "Das7002", "DAS7002" and "daS7002" as different. What needs to be case sensitive is the password but not the login and users will expect it not to be. Examples: this forum, pw, guildwars, gmail/google+, facebook, steam, etc. In fact I only know of one large scale counter example which is linux (and that's mostly for historical reasons).

The point of salting is not to add a "secret" to the hash, anyone who gains access to your server will known it anyway.
Code:
md5('mysecret'.$pass);
is less secure than PW's method. The reason is that the salt is here to prevent bulk cracking. No salt means a pure md5 hashing, it can be easily cracked by using premade table of hash (or even :P:). A fixed salt means no premade table will work, however you only need to generate a table once and then use it for every single hash. PW's way of salting is the best one: each user is different, meaning that if you want to crack the passwords you will need to do it one by one.

Hope this helps :D:

P.S. do not use Roller's code as is... escape the user input DX
 
// Perfect World encrypt password method
$encrypted_Password = $Login.$Password;
$encrypted_Password = md5($encrypted_Password);
$encrypted_Password = "0x".$encrypted_Password;

$sql="SELECT * FROM users WHERE name='$Login' and passwd='$encrypted_Password'";
$result=mysql_query($sql);

Try that, and please people don't crucify me for not adding strtolower.

I would never crucify you (or anyone else) for not using strtolower on the password, that's not a good idea imho; passwords SHOULD be case sensitive...

Finaly, I did another way... The "passwd2" in users table is not used by the pwserver. So I decided to changed the register script a little bit. When a player do an account it creates the same password both for the website and the game but encrypted differently in the two column "passwd" and "passwd2". And in the change password script, it will change the password in the two column.

Ding ding! Problem solved! :P:

OMG I am so happy to see someone around here has this long lost thing... what was it called again...??? Oh yea, common sense :D: (that is not intended as an insult to anyone, not saying anyone else doesn't have it :ott1: [just, well ok, a lot of people around here don't have it :rofl:])

It's actually really common because in most case you do not want to consider the users "das7002", "Das7002", "DAS7002" and "daS7002" as different. What needs to be case sensitive is the password but not the login and users will expect it not to be. Examples: this forum, pw, guildwars, gmail/google+, facebook, steam, etc. In fact I only know of one large scale counter example which is linux (and that's mostly for historical reasons).

The point of salting is not to add a "secret" to the hash, anyone who gains access to your server will known it anyway.
Code:
md5('mysecret'.$pass);
is less secure than PW's method. The reason is that the salt is here to prevent bulk cracking. No salt means a pure md5 hashing, it can be easily cracked by using premade table of hash (or even :P:). A fixed salt means no premade table will work, however you only need to generate a table once and then use it for every single hash. PW's way of salting is the best one: each user is different, meaning that if you want to crack the passwords you will need to do it one by one.

Hope this helps :D:

P.S. do not use Roller's code as is... escape the user input DX

I have to agree here. I know of several sites or 'services' where they do NOT use strtolower, but I know a larger number of sites or 'services' that DO, because as you pointed out (as I have before) I do not want the users:

threefourthree
THREEFOURTHREE
ThreeFourThree
tHREEfOURtHREE
ThReEfOuRtHrEe
tHrEeFoUrThReE
THREEfourTHREE
threeFOURthree
and so on

being considered DIFFERENT users (that would mean I would have 8 different users right there instead of ONE)!!! Which I think is absolutely retarded (and a pain in the ass for any type of 'admin') Why NOT use strtolower where all those would be 'the same user'!

(my previous rant on using StrToLower can be found here, in this thread - http://forum.ragezone.com/f694/user-panel-780123/)
 
threefourthree
THREEFOURTHREE
ThreeFourThree
tHREEfOURtHREE
ThReEfOuRtHrEe
tHrEeFoUrThReE
THREEfourTHREE
threeFOURthree
and so on

users "das7002", "Das7002", "DAS7002" and "daS7002" as different.

You don't. You do what any smart person does and add a unique index on the column that has usernames and emails! If the coalition if case insensitive (which it is by default) then guess what! It prevents those variations from being inserted! :O

Then there is also the fact that when the coalition is case insensitive using strtolower is entirely pointless as DAS7002 and das7002 are the exact same thing to the database. (as well as all the examples 343 gave)

*mumbles something about how I was right all along*
 
You don't. You do what any smart person does and add a unique index on the column that has usernames and emails! If the coalition if case insensitive (which it is by default) then guess what! It prevents those variations from being inserted! :O

Then there is also the fact that when the coalition is case insensitive using strtolower is entirely pointless as DAS7002 and das7002 are the exact same thing to the database. (as well as all the examples 343 gave)

*mumbles something about how I was right all along*
You can use collations to achieve the same goal indeed (although some SQL servers may require you to use "LIKE" rather than "="). It even have the advantage to let you retrieve the username in the original case if needed.

The problem however is that internally PW changes the login to lower case before calculating the hash, so it is not really a solution if you want to use the same data.
 
sorry, I won't read everything to see if someone gave the correct answer xD

As Goodlookinguy told me, the correct way to use password is the md5 hashing of login+password in the byte form. To do that in php: md5($login.$password, true) ... true defines the raw output. read about it here:

The "0x" is something that tells to the database that the following characters will be hex.

Also, you need these procedures if you want it working 100%:



I hope I could help and sorry again if the thread was already correctly answered. Good luck Romulan.
 
Back