6.x password hash generation

So i guess it is pretty obvious about what am i going to ask =)

Problem is, previousle we could just sha1 username and password separated by colon and here is the sha_pass_hash.

The problem i am facing right now, is that according to https://github.com/TrinityCore/TrinityCore/blob/86b98686a95e23247ecb774fb23ecd5b8d94b97b/src/server/game/Accounts/BattlenetAccountMgr.cpp#L177 Trinity now uses SHA256, so the hashes do not match anymore. The thing is, password length in database is 40 symbols (exactly as many as in sha1 hash), but sha256 hash length is 64 characters long. I am confused…

I’ve tried to recreate whole “Cryptography” thing on PHP but, guess what, failed.

Can somebody explain me how the password is generated nowadays?

Thank you for your attention.

There seem to be 2 password hashes generated.
One for the username and pass in auth.account and one for the username and pass in auth.battlenet_accounts.

The latter contains what you look for.

I didnt actually look into the code so no idea if the account table password is used etc.

@Rochet2 Thanks for your reply, however, i still have 0 understanding on how either of them is generated

How did you try generating them? Can you share code?
How did you test your generations?
Did you try generating both of them or only one of them, which one?

It looks to me like both of them are done the same way (with different hashes), except in the bnet one the username is hashed and then hashed with the password.
Also the bnet one will be reversed, which means that instead of being 12345 it is 54321 (the bytes converted to hex will be in reverse order)

All parts (username, password, email) will be converted to uppercase before hashing. (see Utf8ToUpperOnlyLatin function)

How it looks to me:
normal hash - make everything uppercase, use sha1 to hash username:password. it should be noted that username is probably the 1#1 string.
bnet hash - make everything uppercase, use sha256 to hash email then use sha256 to hash hashedemail:password and that hash is reversed. Now email is used as the “username”.

The c++ code enforces some restrictions like length, characters the emails etc can contain and so.

https://github.com/TrinityCore/TrinityCore/blob/86b98686a95e23247ecb774fb23ecd5b8d94b97b/src/server/game/Accounts/AccountMgr.cpp#L387
https://github.com/TrinityCore/TrinityCore/blob/86b98686a95e23247ecb774fb23ecd5b8d94b97b/src/server/game/Accounts/BattlenetAccountMgr.cpp#L177

I am checking against hashes which are made by the worldserver application.

I’ve managed to get hash for battlenet_accounts with following function

strtoupper(bin2hex(strrev(hex2bin(strtoupper(hash(“sha256”,strtoupper(hash(“sha256”, strtoupper($username)).“:”.strtoupper($password))))))));

Now i have some thoughts about the account table... Will share if i will succeed

Well… i pretended that i am really stupid (well, it seems that actually i am) and tried to simply use the username column from the account database… It worked, hash for the account database is the

$username = '1#1'; echo sha1(strtoupper($username . ':' . $password))

Thanks, now I can create a web app to create accounts. I'll share it later!

Is there a reason why you don’t use the other hash or different method for the web app

hey guys. i try to create web application in python with flask for this core but for creating hash in battlenet_accounts table i cant figure it out how it work exactly. if someone could help, that would be nice. i’m following this part of code to making this:

strtoupper(bin2hex(strrev(hex2bin(strtoupper(hash(“sha256”,strtoupper(hash(“sha256”, strtoupper($username)).“:”.strtoupper($password))))))));

my python code:

username = “admin”
password = “admin”

To uppercase

username = username.upper()
password = password.upper()

username to hash

username = hashlib.sha256(username.encode(‘utf-8’))
username = username.hexdigest()

combine username(hash) with password and convert to uppercase

username_password = str((username + “:” + password).upper())

hash username and password and convert to uppercase

username_password = hashlib.sha256(username_password.encode(‘utf-8’))
username_password = str(username_password.hexdigest()).upper()

convert hex to bin

username_password = “{0:08b}”.format(int(username_password, 16))

rev string

username_password = str(username_password[::-1])

convert bin to hex

username_password = ‘%08X’ % int(username_password, 2)

string to uppercase

username_password = str(username_password.upper())
print(username_password)

[ATTACH]2610._xfImport[/ATTACH]

check https://github.com/TrinityCore/WoWSimpleRegistration