php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64211 sha256 hashes "#", "&", and "+" incorrectly.
Submitted: 2013-02-14 11:05 UTC Modified: 2013-02-15 13:56 UTC
From: pwormer at science dot ru dot nl Assigned:
Status: Not a bug Package: hash related
PHP Version: 5.4.11 OS: windows/linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: pwormer at science dot ru dot nl
New email:
PHP Version: OS:

 

 [2013-02-14 11:05 UTC] pwormer at science dot ru dot nl
Description:
------------
The JavaScript functions at:

http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha256.js

and 

http://www.movable-type.co.uk/scripts/sha256.html

give the same hash for any password  of any length consisting of ASCII 32 through 128.  Almost always the hash is the same as obtained from PHP:  hash("sha256", $pswd).

Exceptions (bugs?) are passwords containing one or more of the three characters:
"#" (number sign), "&" (ampersand), or "+" (plus sign).

Tested with XAMPP (PHP 5.4.7), FireFox and Chrome and Linux server.

Test script:
---------------
See http://www.theochem.ru.nl/~pwormer/sha256bug.php

This URL calls SHA256.php which contains the following four lines

<?php
$pswd = $_GET["pswd"];
echo hash("sha256", $pswd);
?>    

Expected result:
----------------
I expect JavaScript and PHP to give same Sha-256 hashes

Actual result:
--------------
Hash of # (single character):

JS:  334359b90efed75da5f0ada1d5e6b256f4a6bd0aee7eb39c0f90182a021ffc8b
PHP: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-02-14 21:37 UTC] sixd@php.net
-Status: Open +Status: Not a bug
 [2013-02-14 21:37 UTC] sixd@php.net
Can't reproduce on 32 or 64 bit Linux:
$ php53 -r 'echo hash("sha256", "#") . "\n";'
334359b90efed75da5f0ada1d5e6b256f4a6bd0aee7eb39c0f90182a021ffc8b
$ php54 -r 'echo hash("sha256", "#") . "\n";'
334359b90efed75da5f0ada1d5e6b256f4a6bd0aee7eb39c0f90182a021ffc8b

Is it coincidence that "" (an empty string) gives the hash you are expecting for 
"#".

$ php53 -r 'echo hash("sha256", "") . "\n";'
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
$ php54 -r 'echo hash("sha256", "") . "\n";'
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
 [2013-02-14 21:38 UTC] sixd@php.net
s/expecting/getting
 [2013-02-15 10:29 UTC] pwormer at science dot ru dot nl
Two more examples:

1. Password "a b" (no quotes, pswd contains three characters, middle one ASCII 32):
JS-hashed password :  c8687a08aa5d6ed2044328fa6a697ab8e96dc34291e8c2034ae8c38e6fcc6d65
PHP-hashed password:  c8687a08aa5d6ed2044328fa6a697ab8e96dc34291e8c2034ae8c38e6fcc6d65

2. Password "a#b" (no quotes, pswd contains three characters, middle one ASCII 35):
JS-hashed password : 8187fc8f7f007036dffc199544b33167632c7739733785bbdec0fbb9a2c43ca1
PHP-hashed password: ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb

My problem is the difference in hash between JavaScript and PHP that occurs if and only if the pswd contains anywhere #, & or +. By looking at PHP alone this problem cannot be solved.
 [2013-02-15 10:40 UTC] pwormer at science dot ru dot nl
I call PHP from JS through XMLHttp.open("GET", "SHA256.php?pswd="+pswd). Maybe the problem lies in XMLHttp?
 [2013-02-15 11:00 UTC] johannes@php.net
That'S your problem. You have to escape the URL parameters.
 
 pswd = "a#b";
 url = "SHA256.php?pswd="+pswd

will create the URL "SHA256.php?pswd=a#b" the browser will then cut of the "#b" from the URL before sending it to the server.

$ php -r 'echo hash("sha256", "a");'
ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb

Which is what you get. You should escape the data ... 

Additional comment: Don't transfer the password as part of the URL. URLs are stored in browser history etc. and might leak therefore. Always use POST data for that. (but still mind proper escaping)
 [2013-02-15 13:56 UTC] pwormer at science dot ru dot nl
Thank you, forgetting to encode was indeed my problem. What threw me off was that almost all special characters (slash, period, at-sign, angular brackets, etc) worked OK without encoding. 

Your point about GET versus POST is well taken. I used GET so far because I'm in an exploration phase. In my definite code I will either use POST or don't hash  on the client, I have to think more about it.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 03:01:28 2024 UTC