[PHP] sha256

Pagina: 1
Acties:
  • 188 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Anoniem: 93582

Topicstarter
Ik ben bezig om de 256bit SHA hash functies te maken in PHP, maar ik kom er even niet uit waar het fout gaat.

Het probleem is als volgt:
Ik krijg op 2 verschillende servers, 2 verschillende hashes en geen 1 is de goeie.

In de for loop die 63 keer doorlopen wordt per blok, gaat het de eerste keer goed, hierna kloppen de hex waardes niet meer.

Dit zijn de eerste 2 regels uit de tabel zoals het zou moeten zijn:
t = 0 : 5d6aebcd 6a09e667 bb67ae85 3c6ef372 fa2a4622 510e527f 9b05688c 1f83d9ab
t = 1 : 5a6ad9ad 5d6aebcd 6a09e667 bb67ae85 78ce7989 fa2a4622 510e527f 9b05688c

Localhost wordt het dit: (windows xp pro, apache 2.0.52, php 5.0.5)
t = 0 : 5d6aebcd 6a09e667 bb67ae85 3c6ef372 fa2a4622 510e527f 9b05688c 1f83d9ab
t = 1 : ffbdf02d 5d6aebcd 6a09e667 bb67ae85 1e219009 fa2a4622 510e527f 9b05688c (deze regel is dus al fout let op 1ste en 5de regel)

en op domein a: (linux, apache 2.0.x en php 5.0.x weet de versie nummers niet precies kan het wel uitzoeken als dat van belang is)
t = 0 : 5d6aebcd 6a09e667 bb67ae85 3c6ef372 fa2a4622 510e527f 9b05688c 1f83d9ab
t = 1 : f9bdb02d 5d6aebcd 6a09e667 bb67ae85 18215009 fa2a4622 510e527f 9b05688c (ook deze regel is dus al fout en niet gelijk aan die van localhost, uiteraard wel zelfde script)

Dit document gebruik ik als bron voor mijn functies
http://csrc.nist.gov/publ...2/fips1...hangenotice.pdf

Heeft iemand enig idee waar het fout zou kunnen gaan.

Ik zit zelf de denken dat het bij het bitshiften fout gaat, maar waar?
Ook kan het zitten in het bereken van $iTemp1 aangezien deze gebruikt wordt bij het berekenen van de 1ste en de 5de waarde uit de hash tabel en het hier blijkbaar fout gaat. (maar ook deze berekening maakt gebruik van bitshiften)

Alvast bedankt

Justin
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<?php
###################################################################
# SHA hash calculator
# Author: Justin Verweel
# Date: 17-10-2005
# Current version: 0.1
# Last modification date: 17-10-2005
#
# License:
# This script is released under the GNU/GPL License.
#
#
# Version History:
# 0.1:
#     - Implementation of the sha256 algorithm
#########################################################################

#Define sequence of sixty-four constant 32-bit words,
#These words represent the first thirty-two bits of the fractional parts of
#the cube roots of the first sixtyfour prime numbers.
$aFracPart = array('1116352408','1899447441','3049323471','3921009573','961987163','1508970993','2453635748','2870763221',
                    '3624381080','310598401','607225278','1426881987','1925078388','2162078206','2614888103','3248222580',
                    '3835390401','4022224774','264347078','604807628','770255983','1249150122','1555081692','1996064986',
                    '2554220882','2821834349','2952996808','3210313671','3336571891','3584528711','113926993','338241895',
                    '666307205','773529912','1294757372','1396182291','1695183700','1986661051','2177026350','2456956037',
                    '2730485921','2820302411','3259730800','3345764771','3516065817','3600352804','4094571909','275423344',
                    '430227734','506948616','659060556','883997877','958139571','1322822218','1537002063','1747873779',
                    '1955562222','2024104815','2227730452','2361852424','2428436474','2756734187','3204031479','3329325298');

/* sha256
*
* @Param    String        The string which will be hashed
* @Return    String        The SHA-256 hash of the input string
*/
function sha256($sStr){
    global $aFracPart;
    #Split the string in bloks
    $aBloks = str2bloksSHA256($sStr);
    
    #Define the initial hash values
    $iA = 1779033703;
    $iB = 3144134277;
    $iC = 1013904242;
    $iD = 2773480762;
    $iE = 1359893119;
    $iF = 2600822924;
    $iG = 528734635;
    $iH = 1541459225;
    
    for ($i = 0; $i < count($aBloks); $i += 16){
        $iOldA = $iA;
        $iOldB = $iB;
        $iOldC = $iC;
        $iOldD = $iD;
        $iOldE = $iE;
        $iOldF = $iF;
        $iOldG = $iG;
        $iOldH = $iH;
        
//For testing only, show the hash build table
                echo '<table>';
        echo '<tr>';
            echo '<td>&nbsp;</td>';
            echo '<td>A</td>';
            echo '<td>B</td>';
            echo '<td>C</td>';
            echo '<td>D</td>';
            echo '<td>E</td>';
            echo '<td>F</td>';
            echo '<td>G</td>';
            echo '<td>H</td>';
            echo '</tr>';
        
         for($j = 0; $j < 64; $j++){
            if($j < 16){
                $w[$j] = $aBloks[$i + $j];
            } else{
                $w[$j] = sigma1_256($w[$j-2]) + $w[$j-7] + sigma0_256($w[$j-15]) + $w[$j-16];
            }
            $iTemp1 = $iH + bigSigma1_256($iE) + ch($iE,$iF,$iG) + $aFracPart[$j] + $w[$j];
            $iTemp2 = bigSigma0_256($iA) + maj($iA,$iB,$iC);
            $iH = $iG;
            $iG = $iF;
            $iF = $iE;
            $iE = $iD + $iTemp1;
            $iD = $iC;
            $iC = $iB;
            $iB = $iA;
            $iA = $iTemp1 + $iTemp2;
            
            echo '<tr>';
            echo '<td>'.$j.'</td>';
            echo '<td>'.dechex($iA).'</td>';
            echo '<td>'.dechex($iB).'</td>';
            echo '<td>'.dechex($iC).'</td>';
            echo '<td>'.dechex($iD).'</td>';
            echo '<td>'.dechex($iE).'</td>';
            echo '<td>'.dechex($iF).'</td>';
            echo '<td>'.dechex($iG).'</td>';
            echo '<td>'.dechex($iH).'</td>';
            echo '</tr>';
        }
        echo '</table>';
        
        $iA += $iOldA;
        $iB += $iOldB;
        $iC += $iOldC;
        $iD += $iOldD;
        $iE += $iOldE;
        $iF += $iOldF;
        $iG += $iOldG;
        $iH += $iOldH;
    }

    //echo 'De sha256 hash:'.dechex($iA).' '.dechex($iB).' '.dechex($iC).' '.dechex($iD).' '.dechex($iE).' '.dechex($iF).' '.dechex($iF).' '.dechex($iH);
    return '<strong>De sha256 hash:</strong> '.dechex($iA).' '.dechex($iB).' '.dechex($iC).' '.dechex($iD).' '.dechex($iE).' '.dechex($iF).' '.dechex($iF).' '.dechex($iH);
    //return sprintf("%08s%08s%08s%08s%08s%08s%08s%08s", dechex($iA), dechex($iB), dechex($iC), dechex($iD), dechex($iE), dechex($iF), dechex($iG), dechex($iH));
    
}

/* str2bloksSHA256
*
* @Param    String        The string which will be seperated into bloks
* @Return    Array        An array representatation of the bloks
*/
function str2bloksSHA256($sStr){
    #Calculate the number of bloks
    $iNumberOfBloks = ((strlen($sStr) + 8) >> 6) + 1;
    
    for($i=0; $i < $iNumberOfBloks * 16; $i++) $aBloks[$i] = 0;
    for($i=0; $i < strlen($sStr); $i++) {
        $aBloks[$i >> 2] |= ord(substr($sStr, $i, 1)) << (24 - ($i % 4) * 8);
    }
    $aBloks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
    $aBloks[$iNumberOfBloks * 16 - 1] = strlen($sStr) * 8;
    
    //For testing only, show the blocks array en his hex value
    echo '<pre>'; print_r($aBloks); echo '</pre>';
    foreach ($aBloks as $value){
        echo dechex($value).'<br/>';
    }

    return $aBloks;

}

function ch($b, $c, $d){
    /*
        ( $b AND $c ) XOR ( ( NOT $b ) AND $d )
    */
    return (($b & $c) ^ ((~$b) & $d));
}
function maj($b, $c, $d){
    /*
        ( $b AND $c ) XOR ( $b AND $d ) XOR ( $c AND $d )

        ( $b AND $c ) => 0001 AND 0010 = 0000
        ( $b AND $d ) => 0001 AND 0011 = 0001
        ( $c AND $d ) => 0011 ADN 0010 = 0010

        $bc XOR $bd XOR $cd => 0000 XOR 0001 = 0001 XOR 0010 = 0011
    */
    return (($b & $c) ^ ($b & $d) ^ ($c & $d));
}

/* Rotates x right n bits. */
function rotateRight($x, $n){
    return (($x >> $n) | ($x << sizeof($x) * 32 - $n));
}
 /* Shift x right n bits */
function shiftRight($x, $n){
    return ($x >> $n);
}

function bigSigma0_256($x){
    return (rotateRight($x, 2) ^ rotateRight($x, 13) ^ rotateRight($x, 22));
}
function bigSigma1_256($x){
    return (rotateRight($x, 6) ^ rotateRight($x, 11) ^ rotateRight($x, 25));
}

function sigma0_256($x){
    return (rotateRight($x, 7) ^ rotateRight($x, 18) ^ shiftRight($x, 3));
}
function sigma1_256($x){
    return (rotateRight($x, 17) ^ rotateRight($x, 19) ^ shiftRight($x, 10));
}


echo sha256('abc');
//sha256('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq');


?>

Acties:
  • 0 Henk 'm!

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 24-04 13:55

glashio

C64 > AMIGA > PC

code:
1
$iB = 3144134277;
PHP gebruikt signed integers... je getal is te groot en wordt vervolgens negatieve waarde :)
he maximum value depends on the system. 32 bit systems have a maximum signed integer range of -2147483648 to 2147483647. So for example on such a system, intval('1000000000000') will return 2147483647. The maximum signed integer value for 64 bit systems is 9223372036854775807.

[ Voor 4% gewijzigd door glashio op 18-10-2005 14:51 ]

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 18-04 09:02
denk het ook. Uit de manual:
Don't right shift for more than 32 bits on 32 bits systems. Don't left shift in case it results to number longer than 32 bits.
In rotateRight zou het dus mis kunnen gaan.

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
hier een werkende unsigned right shift:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
    function urshift($integer, $n){
        if(0xffffffff < $integer || -0xffffffff > $integer) $integer = fmod($integer, 0xffffffff + 1);
        if(0x7fffffff < $integer) $integer -= 0xffffffff + 1.0;
        elseif (-0x80000000 > $integer) $integer += 0xffffffff + 1.0;
        if(0>$integer) {
            $integer &= 0x7fffffff;
            $integer >>= $n;
            $integer |= 1 << (31 - $n);
        } else {
            $integer >>= $n;
        }
        return $integer;
    }


(gevonden in een PHP script voor TEA encryptie)

Acties:
  • 0 Henk 'm!

Anoniem: 93582

Topicstarter
Oke, bedankt.
Dit was me nog niet opgevallen.

Heeft PHP nog grotere datatype? Ik heb al gezocht op long, maar die wordt volgens mij niet ondersteund door PHP.

Zo niet, iemand een idee hoe ik dat alsnog werkend kan maken?
Of is anders de enige optie wachten tot een volgende versie van php waarbij de C implementatie van de sha2 functies al in PHP gebakken zit? :P (of eventueel het datatype long accepteerd)

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 23-04 16:41

drm

f0pc0dert

Misschien heb je hier iets aan: http://nl2.php.net/manual/en/ref.gmp.php

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Anoniem: 93582 schreef op dinsdag 18 oktober 2005 @ 15:08:
Zo niet, iemand een idee hoe ik dat alsnog werkend kan maken?
Of is anders de enige optie wachten tot een volgende versie van php waarbij de C implementatie van de sha2 functies al in PHP gebakken zit? :P (of eventueel het datatype long accepteerd)
deels offtopic, maar als je die sha2 functies nodig hebt, kan je wellicht ook een PHP extension schrijven waar mee je die functies implementeerd :)
http://www.php.net/manual/en/zend.creating.php

Acties:
  • 0 Henk 'm!

Anoniem: 93582

Topicstarter
@Erkens

Bedankt voor het meedenken, voor bij mij thuis is dit geen probleem.
Maar ik wil de sha2 hashes gaan gebruiken op websites die ik host op een virtual server.

Dus ik kan PHP niet zo 1,2,3 opnieuw compileren met de C implementatie van de sha2 functies.

En de hoster wil ook niet echt mee werken helaas. :'(

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Anoniem: 93582 schreef op dinsdag 18 oktober 2005 @ 15:35:
@Erkens

Bedankt voor het meedenken, voor bij mij thuis is dit geen probleem.
Maar ik wil de sha2 hashes gaan gebruiken op websites die ik host op een virtual server.

Dus ik kan PHP niet zo 1,2,3 opnieuw compileren met de C implementatie van de sha2 functies.

En de hoster wil ook niet echt mee werken helaas. :'(
Als je weet welke versie van PHP de hoster draait kan je die source downloaden en je extension daartegen compilen :)
En indien safe_mode niet aan staat kan je de extension dynamisch laden.

offtopic:
persoonlijk zou ik niet mijn sites bij een hoster willen hebben die niet mee werkt

Acties:
  • 0 Henk 'm!

Anoniem: 93582

Topicstarter
@Erkens

Sorry vergeten te melden..
SafeMode staat aan op hun servers... :) Dat is zeker geen goed punt :9 ??

Acties:
  • 0 Henk 'm!

Anoniem: 27270

Misschien kun je eens kijken in de PEAR source? http://pear.php.net/packa.../Message_Hash_SHA256.html Of gewoon meteen deze class gebruiken ?

Dom, deze gebruikt de mhash extensie... sorry (misschien de mhash source uit pecl trekken ofzo?)

[ Voor 25% gewijzigd door Anoniem: 27270 op 18-10-2005 16:04 ]


Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 11-04 11:18
(jarig!)
Misschien kan je het met een ander CGI script proberen: in bijvoorbeeld Perl, die kan je dan aanroepen in je PHP script met een simpele fopen('http://localhost/iets.pl?string='.$tohash);

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Ik heb het probleem met de integers opgelost door een BigInt php class te schrijven die het roteren, shiften en adden voor z'n rekening neemt. Met deze class werkt het nu wel goed.
Code is te vinden op http://dev.barad-dur.nl/sha256/

Oh ja (best belangrijk) het werkt momenteel alleen met korte strings! < 448 bits
korte string probleem is ook gefixt. Theoretisch moet het mogelijk zijn ook bestanden te hashen maar pin me d'r niet op vast.

[ Voor 35% gewijzigd door MTWZZ op 22-10-2005 18:22 ]

Nu met Land Rover Series 3 en Defender 90

Pagina: 1