PHP sha256 хеширование паролей возвращает другой дайджест при работе на Linux

У меня есть следующий класс php, который генерирует дайджест sha256.

<?php

class AuthSha256
{
/**
* On Bits for sha256 mapping
*
* @access  private
* @var     array
*/
private $m_lOnBits  = array(1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215,33554431,67108863,134217727,268435455,536870911,1073741823,2147483647);

/**
* 2nd power sha256 mapping
*
* @access  private
* @var     array
*/
private $m_l2Power  = array(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824);

/**
* Hex mapping sha256 mapping
*
* @access  private
* @var     array
*/
private $K          = array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);


/**
* Perform SHA256 encoding
*
* @access  public
* @param   string      String to encode
* @return  string      Encoded string
*/
public function SHA256($sMessage)
{

$HASH   = array(
0x6A09E667,
0xBB67AE85,
0x3C6EF372,
0xA54FF53A,
0x510E527F,
0x9B05688C,
0x1F83D9AB,
0x5BE0CD19);

$M      = $this->ConvertToWordArray( $sMessage );

for( $i = 0; $i < count($M); $i+=16 )
{
$a = $HASH[0];
$b = $HASH[1];
$c = $HASH[2];
$d = $HASH[3];
$e = $HASH[4];
$f = $HASH[5];
$g = $HASH[6];
$h = $HASH[7];

for( $j = 0; $j<=47; $j++ )
{
if($j < 16)
{
$W[$j] = $M[$j + $i];
}
else
{
$W[$j] = $this->AddUnsigned($this->AddUnsigned($this->AddUnsigned($this->Gamma1($W[$j - 2]), $W[$j - 7]), $this->Gamma0($W[$j - 15])), $W[$j - 16]);
}

$T1 = $this->AddUnsigned($this->AddUnsigned($this->AddUnsigned($this->AddUnsigned($h, $this->Sigma1($e)), $this->Ch($e, $f, $g)), $this->K[$j]), $W[$j]);
$T2 = $this->AddUnsigned($this->Sigma0($a), $this->Maj($a, $b, $c));

$h = $g;
$g = $f;
$f = $e;
$e = $this->AddUnsigned($d, $T1);
$d = $c;
$c = $b;
$b = $a;
$a = $this->AddUnsigned($T1, $T2);
}

$HASH[0] = $this->AddUnsigned($a, $HASH[0]);
$HASH[1] = $this->AddUnsigned($b, $HASH[1]);
$HASH[2] = $this->AddUnsigned($c, $HASH[2]);
$HASH[3] = $this->AddUnsigned($d, $HASH[3]);
$HASH[4] = $this->AddUnsigned($e, $HASH[4]);
$HASH[5] = $this->AddUnsigned($f, $HASH[5]);
$HASH[6] = $this->AddUnsigned($g, $HASH[6]);
$HASH[7] = $this->AddUnsigned($h, $HASH[7]);
}

return
strtolower(
substr("00000000".dechex($HASH[0]), -6)
.substr("00000000".dechex($HASH[1]), -6)
.substr("00000000".dechex($HASH[2]), -6)
.substr("00000000".dechex($HASH[3]), -6)
.substr("00000000".dechex($HASH[4]), -6)
.substr("00000000".dechex($HASH[5]), -6)
.substr("00000000".dechex($HASH[6]), -6)
.substr("00000000".dechex($HASH[7]), -6));
}

/**
* Left shift a value x bits
*
* @access  private
* @param   string      String to shift
* @param   integer     Number of bits to shift
* @return  string      Shifted string
*/
private function LShift($lValue, $iShiftBits)
{
if ($iShiftBits == 0)
{
return $lValue;
}
elseif ($iShiftBits == 31)
{
if ($lValue & 1)
{
$un = unpack("l", pack("l", hexdec('0x80000000')));
return reset($un);
}
else
{
return 0;
}
}
elseif ($iShiftBits < 0 Or $iShiftBits > 31)
{
exit();
}

if ($lValue & $this->m_l2Power[31 - $iShiftBits])
{
$un2=unpack("l", pack("l", hexdec('0x80000000')));
return (($lValue & $this->m_lOnBits[31 - ($iShiftBits + 1)]) * $this->m_l2Power[$iShiftBits]) | reset($un2);
}
else
{
return (($lValue & $this->m_lOnBits[31 - $iShiftBits]) * $this->m_l2Power[$iShiftBits]);
}
}

/**
* Right shift a value x bits
*
* @access  private
* @param   string      String to shift
* @param   integer     Number of bits to shift
* @return  string      Shifted string
*/
private function RShift($lValue, $iShiftBits)
{
if ($iShiftBits == 0)
{
return $lValue;
}
elseif ($iShiftBits == 31)
{
$un3 = unpack("l", pack("l", hexdec('0x80000000')));
if ($lValue & reset($un3))
{
$RShift = 1;
}
else
{
$RShift = 0;
}
}
elseif ($iShiftBits < 0 Or $iShiftBits > 31)
{
exit();
}

$unpack = unpack("l", pack("l", hexdec('0x7FFFFFFE')));
$rese = reset($unpack);
$RShift = floor(($lValue & $rese) / $this->m_l2Power[$iShiftBits]);

$unpack1 = unpack("l", pack("l", hexdec('0x80000000')));
if ($lValue & reset($unpack1))
{
$unpack2 = unpack("l", pack("l", hexdec('0x40000000')));
$RShift = ($RShift | floor(reset($unpack2)) / $this->m_l2Power[$iShiftBits - 1]);
}

return $RShift;
}

/**
* Add unsigned
*
* @access  private
* @param   integer     Number
* @param   integer     Number
* @return  string      Added unsigned integer
*/
private function AddUnsigned($lX, $lY)
{
$unp1 = unpack("l", pack("l", hexdec('0x80000000')));
$unp2 = unpack("l", pack("l", hexdec('0x80000000')));
$unp3 = unpack("l", pack("l", hexdec('0x40000000')));
$unp4 = unpack("l", pack("l", hexdec('0x40000000')));
$lX8 = $lX & reset($unp1);
$lY8 = $lY & reset($unp2);
$lX4 = $lX & reset($unp3);
$lY4 = $lY & reset($unp4);

$unp5 = unpack("l", pack("l", hexdec('0x3FFFFFFF')));
$lResult = ($lX & reset($unp5)) + ($lY & reset($unp5));

if ($lX4 & $lY4)
{
$lResult = $lResult ^ reset($unp1) ^ $lX8 ^ $lY8;
}
elseif ($lX4 | $lY4)
{
if ($lResult & reset($unp3))
{
$unp6 = unpack("l", pack("l", hexdec('0xC0000000')));
$lResult = $lResult ^ reset($unp6) ^ $lX8 ^ $lY8;
}
else
{
$lResult = $lResult ^ reset($unp3) ^ $lX8 ^ $lY8;
}
}
else
{
$lResult = $lResult ^ $lX8 ^ $lY8;
}

return $lResult;
}

/**
* Ch
*
* @access  private
* @param   integer     $x
* @param   integer     $y
* @param   integer     $z
* @return  mixed       No idea...
*/
private function Ch($x, $y, $z)
{
return (($x & $y) ^ ((~ $x) & $z));
}

/**
* Maj
*
* @access  private
* @param   integer     $x
* @param   integer     $y
* @param   integer     $z
* @return  mixed       No idea...
*/
private function Maj($x, $y, $z)
{
return (($x & $y) ^ ($x & $z) ^ ($y & $z));
}

/**
* S
*
* @access  private
* @param   integer     $x
* @param   integer     $n
* @return  mixed       No idea...
*/
private function S($x, $n)
{
return ($this->RShift($x , ($n & $this->m_lOnBits[4])) | $this->LShift($x , (32 - ($n & $this->m_lOnBits[4]))));
}

/**
* R
*
* @access  private
* @param   integer     $x
* @param   integer     $n
* @return  mixed       No idea...
*/
private function R($x, $n)
{
return $this->RShift($x , ($n & $this->m_lOnBits[4]));
}

/**
* Sigma0
*
* @access  private
* @param   integer     $x
* @return  mixed       No idea...
*/
private function Sigma0($x)
{
return ($this->S($x, 2) ^ $this->S($x, 13) ^ $this->S($x, 22));
}

/**
* Sigma1
*
* @access  private
* @param   integer     $x
* @return  mixed       No idea...
*/
private function Sigma1($x)
{
return ($this->S($x, 6) ^ $this->S($x, 11) ^ $this->S($x, 25));
}

/**
* Gamma0
*
* @access  private
* @param   integer     $x
* @return  mixed       No idea...
*/
private function Gamma0($x)
{
return ($this->S($x, 7) ^ $this->S($x, 18) ^ $this->R($x, 3));
}

/**
* Gamma1
*
* @access  private
* @param   integer     $x
* @return  mixed       No idea...
*/
private function Gamma1($x)
{
return ($this->S($x, 17) ^ $this->S($x, 19) ^ $this->R($x, 10));
}

/**
* Convert to a word array
*
* @access  private
* @param   string      Word to convert
* @return  array       Word array
*/
private function ConvertToWordArray($sMessage)
{
$BITS_TO_A_BYTE = 8;
$BYTES_TO_A_WORD = 4;
$BITS_TO_A_WORD = 32;
$MODULUS_BITS = 512;
$CONGRUENT_BITS = 448;

$lMessageLength = strlen($sMessage);

$lNumberOfWords = (floor(($lMessageLength + floor(($MODULUS_BITS - $CONGRUENT_BITS) / $BITS_TO_A_BYTE)) / floor($MODULUS_BITS / $BITS_TO_A_BYTE)) + 1) * floor($MODULUS_BITS / $BITS_TO_A_WORD);
for($i = 0; $i < $lNumberOfWords; $i++)
{
$lWordArray[$i]="";
}

$lBytePosition = 0;
$lByteCount = 0;
do
{
$lWordCount = floor($lByteCount / $BYTES_TO_A_WORD);

$lBytePosition = (3 - ($lByteCount % $BYTES_TO_A_WORD)) * $BITS_TO_A_BYTE;

$lByte = ord(substr($sMessage, $lByteCount, 1));

$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | $this->LShift($lByte , $lBytePosition);
$lByteCount++;
}
while ($lByteCount < $lMessageLength);

$lWordCount = floor($lByteCount / $BYTES_TO_A_WORD);
$lBytePosition = (3 - ($lByteCount % $BYTES_TO_A_WORD)) * $BITS_TO_A_BYTE;

$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | $this->LShift(0x80 , $lBytePosition);

$lWordArray[$lNumberOfWords - 1] = $this->LShift($lMessageLength , 3);
$lWordArray[$lNumberOfWords - 2] = $this->RShift($lMessageLength , 29);

return $lWordArray;
}
}

вот пример кода для генерации дайджеста

<?php
require_once('AuthSha256.php');

$pwd = '1!aAqwerty';
$c = new AuthSha256();
print_r($c-> SHA256($pwd));
?>

Когда я выполняю этот класс в Linux, я получаю этот дайджест 97bc61212297bf380d5462d827b182adf6f956c855ec9c1c но когда я выполняю точно такой же код в Windows, для того же пароля ‘1! aAqwerty’ я получаю совершенно другой дайджест. 20fc88c269c75bda2902f99d020fa966c4e550b42bedddd9,
Кто-нибудь знает, почему это происходит?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]