Jon Bringhurst on 19 Aug 2008 11:48:42 -0700


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] [OT] PHP, binary math, password hashing


So, assuming "BYTE"s are octets, it looks like it's getting the md5 of
the string and then splitting it up into 4 parts. Then, it just XORs
each part together, basically introducing a ton of possible collisions
and making the hash very insecure. Why are you doing this again?

-Jon B

On Tue, Aug 19, 2008 at 2:06 PM, Christopher M. Jones
<cjones@partialflow.com> wrote:
> I'm trying to port a program from C-something to php that generates a
> hash from password, login, and some other data. I've quoted the relevant
> portions of the source code at the end of this message.
>
> I'm struggling on three counts:
>
> 1. Learning binary math
> 2. Reading the source code
> 3. Replicating it in php
>
> I guess that covers everything ;-)
>
> In the source function CalculateFoldedMD5(), it looks like the following
> is happening:
>
> 1. A buffer is created to hold the hash
> 2. The hash is parsed and the bits manipulated
> 3. The bits are recombined
>
> The following vexes me:
>        unsigned int a = (bHash[0x0] << 24) | (bHash[0x1] << 16) | (bHash[0x2]
> << 8) | bHash[0x3];
>
> It looks to me that the construct bHash[0x0] accesses the buffer
> (bHash), which is declared earlier in the function as
>
> BYTE bHash[16] = { 0 }
>
> The buffer length is delared in ComputMD5() as being 16 bits.
>
> So does bHash[0x0] reference the first four bits in the buffer?
>
> If so, then look at this:
>
> unsigned int a = (bHash[0x0] << 24) | (bHash[0x1] << 16) | (bHash[0x2]
> << 8) | bHash[0x3];
>        unsigned int b = (bHash[0x4] << 24) | (bHash[0x5] << 16) | (bHash[0x6]
> << 8) | bHash[0x7];
>        unsigned int c = (bHash[0x8] << 24) | (bHash[0x9] << 16) | (bHash[0xA]
> << 8) | bHash[0xB];
>        unsigned int d = (bHash[0xC] << 24) | (bHash[0xD] << 16) | (bHash[0xE]
> << 8) | bHash[0xF];
>
> If each hex code represents four bits, then these lines account for 64
> bits of hash. What do I need to do to get 64 bits of hash?
>
> I did the following:
>
> $hash = base_convert( md5( $word ), 10, 2);
>
> This gives me a string of 1's or 0's, 64 long. The unconverted hash is
> 32 long. So I'm thinking I did the right thing with base_convert(), but
> I really have no idea. I'm stabbing in the dark.
>
> So IF I've parsed the hash properly, my next question is: how to
> replicate the bHash[0x0] structure. I've got no idea, and this is where
> I've reached a dead end.
>
> ANY help would be appreciated. I'm happy to further clarify my questions
> for anyone who wants to take me as a project.
>
> Both source functions are quoted in full below.
>
> -------------------------------------------------------------
>
> BOOL ComputeMD5(BYTE *bHash, char *pBuffer, unsigned int uLength)
> {
>        HCRYPTPROV hCryptProvider;
>     HCRYPTHASH hHash;
>
>        BOOL bResult = FALSE;
>
>        if (CryptAcquireContext(&hCryptProvider, NULL, NULL, PROV_RSA_FULL,
> CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
>        {
>                if (CryptCreateHash(hCryptProvider, CALG_MD5, 0, 0, &hHash))
>                {
>                        if (CryptHashData(hHash, (BYTE*)pBuffer, uLength, 0))
>                        {
>                                DWORD dwHashLength = 16; // 128 bit hash
>
>                                if (CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwHashLength, 0))
>                                        bResult = TRUE;
>                        }
>                        CryptDestroyHash(hHash);
>                }
>                CryptReleaseContext(hCryptProvider, 0);
>        }
>
>        return bResult;
> }
>
> unsigned int ComputeFoldedMD5(CString& strCheck)
> {
>        CT2CA strAscii(strCheck); // Convert to ANSI
>        BYTE bHash[16] = { 0 };
>
>        if (!ComputeMD5(bHash, strAscii, strlen(strAscii)))
>                return 0;
>
>        unsigned int a = (bHash[0x0] << 24) | (bHash[0x1] << 16) | (bHash[0x2]
> << 8) | bHash[0x3];
>        unsigned int b = (bHash[0x4] << 24) | (bHash[0x5] << 16) | (bHash[0x6]
> << 8) | bHash[0x7];
>        unsigned int c = (bHash[0x8] << 24) | (bHash[0x9] << 16) | (bHash[0xA]
> << 8) | bHash[0xB];
>        unsigned int d = (bHash[0xC] << 24) | (bHash[0xD] << 16) | (bHash[0xE]
> << 8) | bHash[0xF];
>
>        return a ^ b ^ c ^ d;
> }
>
>
> ___________________________________________________________________________
> Philadelphia Linux Users Group         --        http://www.phillylinux.org
> Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
> General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug
>
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug