Jump to content

Help understanding the Intermediate points of SHA256, Base64, and storing hashed passwords


Recommended Posts

Part 1:

I am attempting to "correctly" store hashed (and salted, later) passwords in a database.

I have modified my Crypt.au3 to allow for SHA256 hashing.

I am using the example:   https://www.autoitscript.com/autoit3/docs/libfunctions/_Crypt_HashData.htm

I can hash the data: "hunter2" with the proper result of:

0xF52FBD32B2B3B86FF88EF6C490628285F482AF15DDCB29541F94BCF526A3F6C7

However, when I include code for converting to base64 as such:  (Using Code from: )'>)

Local $bHash = _Crypt_HashData($sRead, $bAlgorithm) ; Create a hash of the text entered.

To:

Local $bHash = _Base64Encode(_Crypt_HashData($sRead, $bAlgorithm)) ; Create a hash of the text entered.

I get the unexpected result of:

MHhGNTJGQkQzMkIyQjNCODZGRjg4RUY2QzQ5MDYyODI4NUY0ODJBRjE1RERDQjI5NTQxRjk0QkNGNTI2QTNGNkM3
Instead of:
9S+9MrKzuG/4jvbEkGKChfSCrxXdyylUH5S89Saj9sc=
 
I believe this is because I am passing a string, instead of ??????  I am not sure.  When I use _Base64Encode("0xF52FBD32B2B3B86FF88EF6C490628285F482AF15DDCB29541F94BCF526A3F6C7") I get the expected result.
Edited by kaisies
Link to comment
Share on other sites

Part 2:

I have looked at how some databases store their passwords hashes, and salts, and they store them as such:

$5$salthere$sha256hash(checksum?)  is hash == checksum in this instance?

I understand that the omission of rounds=#### implies that the default of 5,000 rounds was used.

when looking at the Checksum in examples, I see that there are no = characters at the end.  Reading up on Base64 structure, it seems that = at the end is used to pad the result.  Is this typically dropped when storing this data?

There also seem to be . and /, however the "standard" base64 appears to include only + and /... is there a non standard base64 that is used to store password hashes?  

Link to comment
Share on other sites

I modified Crypt.au3 to add the SHA256 algorithm - presumably the same way you did - by uncommenting line 50 which has the constant for $CALC_SHA_256 .

I then ran the following code which produces correct results:

Local $hash = _Base64Encode(_Crypt_HashData("hunter2", $CALG_SHA_256))
ConsoleWrite($hash & @LF)

; Prints "9S+9MrKzuG/4jvbEkGKChfSCrxXdyylUH5S89Saj9sf=" as expected

I would suggest outputting $sRead, $bAlgorithm, and the result of _Crypt_HashData separately so that you can be sure the various inputs and outputs are what you think they are.

 

As far as your second post:

I understand that the omission of rounds=#### implies that the default of 5,000 rounds was used.

 

I wouldn't be too sure of that, 5000 is a pretty specific number.  Normally, no specified number of rounds means 1 round.  Maybe what you are looking at sees it differently, but I have never heard "5000" as a default (not that I'm an expert).

 

 

when looking at the Checksum in examples, I see that there are no = characters at the end.  Reading up on Base64 structure, it seems that = at the end is used to pad the result.  Is this typically dropped when storing this data?

 

Is the checksum Base64 encoded?  Because the "=" padding is Base64 specific.  Also, one may or may not put the padding on Base64 content depending on the Base64 encoding used.  Whatever you are looking at might be showing the result of an encoding other than RFC2045.  See next answer.

 

 

There also seem to be . and /, however the "standard" base64 appears to include only + and /... is there a non standard base64 that is used to store password hashes?

 

(Old joke warning) The cool thing about standards is that there are so many to choose from. 

Go to the Wikipedia page for Base64 http://en.wikipedia.org/wiki/Base64 and you'll see that there are a number of different encodings.  Some use "+" and "/", others use "." and "/", and etcetera.  Additionally, some pad the end with "=" and "==", while others don't.  My personal experience is that the one I most commonly see is RFC2045, which fits the description of the data you are describing.  However, it's certainly possible to see other encodings.

How's my riding? Dial 1-800-Wait-There

Trying to use a computer with McAfee installed is like trying to read a book at a rock concert.

Link to comment
Share on other sites

I modified Crypt.au3 to add the SHA256 algorithm - presumably the same way you did - by uncommenting line 50 which has the constant for $CALC_SHA_256 .

I then ran the following code which produces correct results:

Local $hash = _Base64Encode(_Crypt_HashData("hunter2", $CALG_SHA_256))
ConsoleWrite($hash & @LF)

; Prints "9S+9MrKzuG/4jvbEkGKChfSCrxXdyylUH5S89Saj9sf=" as expected

I would suggest outputting $sRead, $bAlgorithm, and the result of _Crypt_HashData separately so that you can be sure the various inputs and outputs are what you think they are.

 

I was able to correct this problem by running the command as:  

GUICtrlSetData($iOutputEdit, _Base64Encode(_HexToString($bHash))) ; Set the output box with the hash data.

Thank you for the suggestion

 

 

 

As far as your second post:

 

I wouldn't be too sure of that, 5000 is a pretty specific number.  Normally, no specified number of rounds means 1 round.  Maybe what you are looking at sees it differently, but I have never heard "5000" as a default (not that I'm an expert).

 

I was leaning on this:  https://pythonhosted.org/passlib/lib/passlib.hash.sha256_crypt.html

Which specifies:

There is also an alternate format $5$salt$checksum, which can be used when the rounds parameter is equal to 5000 (see the implicit_rounds parameter above).

 

 

Is the checksum Base64 encoded?  Because the "=" padding is Base64 specific.  Also, one may or may not put the padding on Base64 content depending on the Base64 encoding used.  Whatever you are looking at might be showing the result of an encoding other than RFC2045.  See next answer.

 

(Old joke warning) The cool thing about standards is that there are so many to choose from. 

Go to the Wikipedia page for Base64 http://en.wikipedia.org/wiki/Base64 and you'll see that there are a number of different encodings.  Some use "+" and "/", others use "." and "/", and etcetera.  Additionally, some pad the end with "=" and "==", while others don't.  My personal experience is that the one I most commonly see is RFC2045, which fits the description of the data you are describing.  However, it's certainly possible to see other encodings.

 

Agreed!  And as someone who knows OF them but not much else, it is daunting to look at this, but I do enjoy the challenge.  Spent the whole day googling around and figuring out where to even start and what made sense.  I must admit, I am attempting to emulate how a program works.  I had assumed it was Base64 Specific, because its in the format $5$salt$checksum OR $5$XXXXXXXXXXXXXXXX$YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

 

Where X = 16 Char Salt

Y = Password Hash.  The YYYYYY is always 43 chars, and contains the characters "." and "/" never "+"

 

​My assumption is that since rounds is never specified in the Salted Hash, It can be inferred that it is either a number that is always the same, or is base on another column in the database?  Since you always have to know "rounds" to properly hash the password the correct amount of times.

 

I had read over the Wiki about Base64, and it doesn't seem to list a Variant that uses "." and "/" not "+".  

Edited by kaisies
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...