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

7
使用CryptoJS计算此帖子底部字符串的MD5值,并将其发送到Amazon网络服务,但我计算的MD5值与亚马逊计算的不同。我进行了一些在线测试,发现某些MD5计算网站的计算结果也不同。例如,md5hashgenerator与我计算出相同的值,而onlinemd5计算出与亚马逊相同的值。我需要使用CryptoJS获得与亚马逊相同的MD5值。
- CryptoJS.MD5: ec20007986ee9e1a5152c35d07e87fcc - Amazon Scratchpad 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 上实现相同的结果?
3个回答

5

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计算机上使用LF作为行分隔符,在一个名为“tmp”的文件中存储了您的文本,并进行了如下操作:

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

看这里!!

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


3

由于换行符的存在,返回的哈希值会发生变化。在应用md5哈希之前,您可以剪切并删除字符串中的所有空格。这样结果应该是相同的。以下是使用CryptoJS实现的方法:

const CryptoJS = require("crypto-js");

let string = "xmlString".replace(/\s+/g, '');
let hash = CryptoJS.MD5(string).toString();
console.log(hash);

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


0

同时,我正在对那些在线网站进行一些测试,并且我意识到,“新行”会创建不同的哈希值。我使用了示例字符串进行了一些测试。如果我使用从顶部开始的两行,它们会创建不同的哈希值,如果我只使用示例字符串的顶部一行,则两个网站都会创建相同的哈希值。因此,我正在尝试理解为什么换行符会导致这种情况。 - HOY
这听起来像是每个提供程序都有自己的序列化XML输入的方式,其中偶尔会省略双行,例如。这肯定会产生问题,因为在不同的提供程序中将其转换为字符串的方式不同,并且不同的有效负载会导致不同的哈希值。 - zarnoevic

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