|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
|
[PLUG] [OT] PHP, binary math, password hashing
|
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
|
|