MD5 哈希不同

MD5 hash is Different

在 sql 服务器上:输出: 0x5C8C8AAFE7AE37EA4EBDF8BFA01F82B8

SELECT HASHBYTES('MD5', convert(varchar,getdate(),112)+'mytest@+')

在 JavaScript 上:输出: 5c8c8aafe7ae37ea4ebdf8bfa01f82b8

        //to get Md5 Hash bytes
        vm.getMd5Hashbytes = function () {
            var currentDate = moment().format('YYYYMMDD');
             var md5Hash = md5.createHash(currentDate + 'mytest@+');
             return md5Hash;
        }

angular-md5 module

问:你能告诉我为什么会有这种差异吗? SQL 服务器将 0x 显示为 prefix.Why?

我不确定还能如何解释它,但它需要的 space 比评论所允许的要多,所以我将 post 它作为答案。

查看您引用的 source code。在最后(第 210 和 212 行),您将看到它将二进制值转换为十六进制字符串(,然后转换为小写,这无关紧要,除非您在最后选择字符串比较).最终结果 = 您的 JavaScript 库 returns 使用类型 string 的表示,格式为十六进制。

另一方面,您的 Sql 函数 HASHBYTES 会产生一个 varbinary 类型的结果( 与字符串 (varchar)).

因此您有 2 种不同的数据类型(每种数据类型都独立存在 space,因为您没有将一种数据拉到另一种数据类型)。您永远不会提到您在哪里进行比较,即:在数据库上还是从数据库中提取到脚本。无论哪种方式进行比较,您都需要转换一种类型,因此您要么比较 2 种字符串类型,要么比较两种二进制类型。如果您不比较相似的类型,您将得到意想不到的结果或 运行 时间异常。

如果您使用字符串 AND 在 JavaScript 中进行比较,那么查看您引用的库,它已经有一个名为 wordToHex 的调用,复制并粘贴它并重新使用它来转换您的Sql 结果为字符串,然后进行字符串比较(不要忘记比较不区分大小写或也将其设为小写)。


编辑

WebApi is black box for me.It is a 3rd party service.I just need to send the security token as mentioned above.

假设该网络 api 接受的类型是 byt[]0x 附加到 javascript 中的字符串,然后将其发送到网络 api 应该像在网络中一样工作 api 然后将传入的参数转换为字节数组并使用正确的类型执行比较。由于这是一个黑盒子,因此无法确定,除非您询问他们接受的类型是否确实是字节数组或对其进行测试。

这纯粹是格式问题。两个版本都产生相同的字节序列。 SQL 在以人类可读的格式呈现这些字节时,服务器和节点有不同的约定。

您可以通过专门告诉 SQL 服务器如何格式化您的二进制数据来获得类似的格式

declare @hashAsBinary varbinary(max)
declare @hashAsText char(32)
set @hashAsBinary = HASHBYTES('MD5', '20160818mytest@+')
set @hashAsText = LOWER(CONVERT(varchar(max), @hashAsBinary, 2))
select @hashAsText

输出:

5c8c8aafe7ae37ea4ebdf8bfa01f82b8

SQL Server converting varbinary to string