使用Javascript和PHP生成相同的MD5

3
我正在尝试构建一个应用程序,需要比较任何文件的MD5哈希值。由于特定问题,在上传之前必须在客户端生成MD5,并且上传后应用程序需要在服务器端进行检查。
我的第一种方法是在客户端使用JavaScript File API和FileReader.ReadAs函数。然后我使用在此处找到的MD5算法:http://pajhome.org.uk/crypt/md5/ 服务器端,我将使用PHP的fopen命令和md5函数。
当使用像某些jpg或pdf这样的二进制文件时,这种方法在使用简单文本文件时效果很好。但是,当使用二进制文件(如某些jpg或pdf)时,客户端生成的MD5与服务器不同。使用md5sum命令行工具,我发现服务器MD5是正确的,问题出现在客户端。
我尝试了其他的MD5 API,但结果相同。我怀疑FileReader.ReadAs函数会稍微不同地加载文件内容(我尝试了所有的ReadAs函数变体:文本、二进制等),但我无法找出区别在哪里。
我可能漏掉了什么,但不知道是什么,也许我需要在生成MD5之前以某种方式解码内容。
有什么提示吗?
编辑1:
我按照optima1给出的思路进行操作。将每个字符打印出来,并在javascript和PHP上打印unicode编号。我发现所有情况下只有一个差异(使用vimdiff)。
PHP:54 51 10 37 37 69 79 70 0
Javascript:54 51 10 37 37 69 79 70
也许这个额外的零在PHP中是某种“字符串结尾”。在两种情况下,二进制字符串的长度相同。在JS内容末尾添加String.fromCharCode(0)并不能解决问题。我会继续调查。
如果我找不到解决方案,我会尝试通过连接这些charcodes来构建一个巨大的字符串,并使用它来构建MD5。这是一个糟糕的解决方案,但现在可以使用,并且我只需要在JS字符串的末尾添加一个零...
编辑2:
感谢上帝!这个实现起来像魅力一样:http://www.myersdaily.org/joseph/javascript/md5.js
如果您需要从二进制文件生成MD5哈希,请去做吧。
提前致谢!

你试过这个吗?http://phpjs.org/functions/md5/ http://phpjs.org/functions/md5_file/ - bystwn22
1
是的,我也尝试了这个实现。它生成相同的哈希值。我认为我在文件内容的编码方面漏掉了一些东西。 - marcellorvalle
只是为了确认一下,你没有在任何安全相关的事情中使用md5,对吧? - Simba
不,我不是。别担心。 :) - marcellorvalle
2个回答

2

仅提供链接的答案是不被鼓励的,部分原因是链接可能最终会失效,使得答案变得无用。请从链接中提供一些上下文。 - Robert
我必须加上+1,因为链接的JavaScript实现是唯一一个与PHP在二进制数据方面给出相同结果的(尝试了PhpJs、CryptoJs和其他几个),感谢您挽救了我的一天。 - Romain
一样的,输出完全相同,谢谢Ramakanth! - Leandro Gamarra

0
我建议进行快速的合理性检查:让你的客户端代码报告二进制数据的第一个和最后一个字节。在你的 PHP 代码中重复此操作。比较两种方法的第一个和最后一个字节,以确保它们实际上读取了相同的数据(这应该会导致相同的 MD5 哈希值)。
然后,我建议在这里发布代码,以便我们进行审查。

嗨,我尝试了以下操作:取出每个字符并打印Unicode编号。只有一个区别在结尾处。我使用了一些不同的PDF文件,并通过vimdiff进行了验证。PHP:102 10 49 48 49 53 49 10 37 37 69 79 70 0 JavaScript:102 10 49 48 49 53 49 10 37 37 69 79 70。现在我有点困惑:string.length在JS和PHP上显示相同的大小。还尝试将"String.fromCharCode(0)"附加到JS内容的末尾,但没有成功。编辑:无法使两个空格的换行符起作用... - marcellorvalle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接