同一字符串的不同 MD5 哈希 (CryptoJS.MD5)



使用CryptoJS,我正在计算本文底部字符串的MD5,并将其发送到亚马逊网络服务,但是我计算的MD5值和亚马逊计算不同

所以我做了一些在线测试,并意识到MD5计算在某些md5计算网站中也有所不同。例如,md5hashgenerator计算与我相同的值,onlinemd5计算与亚马逊相同的值。

我需要的是使用CryptoJS获得与亚马逊相同的MD5值

- CryptoJS.MD5:ec20007986ee9e1a5152c35d07e87fcc

- 亚马逊暂存器 MD5:ee288aa4858481d7b1d7422c6fc4b3af

- md5hashgenerator.com:EC20007986EE9E1A5152C35D07E87FCC

- onlinemd5.com:ee288aa4858481d7b1d7422c6fc4b3af


用于计算 MD5 的字符串:

<?xml version="1.0" encoding="iso-8859-1"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>M_EXAMPLE_123456</MerchantIdentifier>
</Header>
<MessageType>Product</MessageType>
<PurgeAndReplace>false</PurgeAndReplace>
<Message>
<MessageID>1</MessageID>
<OperationType>Update</OperationType>
<Product>
<SKU>56789</SKU>
<StandardProductID>
<Type>ASIN</Type>
<Value>B0EXAMPLEG</Value>
</StandardProductID>
<ProductTaxCode>A_GEN_NOTAX</ProductTaxCode>
<DescriptionData>
<Title>Example Product Title</Title>
<Brand>Example Product Brand</Brand>
<Description>This is an example product description.</Description>
<BulletPoint>Example Bullet Point 1</BulletPoint>
<BulletPoint>Example Bullet Point 2</BulletPoint>
<MSRP currency="USD">25.19</MSRP>
<Manufacturer>Example Product Manufacturer</Manufacturer>
<ItemType>example-item-type</ItemType>
</DescriptionData>
<ProductData>
<Health>
<ProductType>
<HealthMisc>
<Ingredients>Example Ingredients</Ingredients>
<Directions>Example Directions</Directions>
</HealthMisc>
</ProductType>
</Health>
</ProductData>
</Product>
</Message>
</AmazonEnvelope>

编辑:经过一些测试,我意识到差异是由于"换行符"字符引起的。所以问题是为什么在这些工具中对换行符的处理方式不同,我如何使用 CryptoJS 与 Amazon 获得相同的结果?

md5(以及其他哈希函数,如sha*,Murmur...(处理二进制数据。因此,如何将文本转换为二进制将更改生成的哈希。显然,UTF-8、UTF-16 或 UTF-32 中的相同文本将具有不同的哈希值。

换行符的情况有点棘手。在古代,人们必须在打字机上敲击两次键才能换行:回车,将打印头放回行的开头,同时保持相同的垂直位置,以及换行,将打印头向下移动一行,同时保持相同的水平位置。

在早期的计算机时代,人们模仿这一点,US-ASCII有两个关于线路终止的代码点:CR(0x0D(和LF(0x0A(。用著名的 CRLF 序列制作了换行符。例如,HTTP/1.0标准要求CRLF作为标头之间的分隔符(我没有检查HTTP/1.1或HTTP/2(。

然后人们开始认为一个概念的两个字符是一种浪费,Unix系统开始只使用LF,而Mac系统(在OS X之前(只使用CR(Windows,嗯,认为你有足够的内存来存储所有这些多余的字节(。

所以我将您的文本存储在 Ubuntu 计算机上一个名为"tmp"的文件中,使用 LF 作为行分隔符,并且:

$ md5sum tmp 
ee288aa4858481d7b1d7422c6fc4b3af  tmp
$ unix2dos tmp 
unix2dos: converting file tmp to DOS format...
$ md5sum tmp 
ec20007986ee9e1a5152c35d07e87fcc  tmp

瞧!!

(unix2dos是将LF转换为CRLF的工具(。

返回的哈希因换行符而异。您可以在应用 md5 哈希之前修剪和删除字符串中的所有空格。这样结果应该是相同的。下面是一个使用CryptoJS的实现:

const CryptoJS = require("crypto-js");
let string = "xmlString".replace(/s+/g, '');
let hash = CryptoJS.MD5(string).toString();
console.log(hash);

我不知道为什么换行符在您使用的工具中处理方式不同,但在删除空格后得到了相同的结果。

一种猜测是,它与其他提供程序在哈希之前对有效负载(在本例中为字符串化 XML(进行加盐有关。我没有看到太多文档,因为它们都是小型免费在线工具。最好明确这一点,因为它可能会导致这样的情况,即您无法确认使用不同盐值计算的哈希值,即使有效负载相同。

CryptoJS似乎没有将盐添加作为显式功能实现。

最新更新