【问题标题】:Delphi - Amazon MWS API - How do derive the Base64 HMAC from the SHA 256 HMAC?Delphi - 亚马逊 MWS API - 如何从 SHA 256 HMAC 派生 Base64 HMAC?
【发布时间】:2021-10-30 20:01:39
【问题描述】:

使用:

  • 德尔福 10.2.3 东京
  • IPWorks SSL、IPWorks 加密

我正在编写一个 Delphi 应用程序以从亚马逊 MWS API 获取订单列表。

我在这里按照他们的指示进行操作:

这里:

但我卡在签名生成过程中,特别是生成 Base64 HMAC。

我正在使用 IPWorks SSL 组件(哈希组件)并且能够根据输入生成 SHA 256 签名。到这一步一切正常。

这是我无法/不确定如何执行的下一步。

我正在使用 Amazon 暂存器生成请求,并且正在查看请求详细信息以及生成的签名:SHA 256 和 Base 64。

我的 Delphi 代码不会像暂存器中生成的那样生成 Base 64 字符串。请参阅随附的屏幕截图(敏感信息已被编辑)。

这是我将 SHA 256 字符串转换为 Base 64 的 Delphi 代码:

procedure TAppMain.Button1Click(Sender: TObject);
var
  s: String;
  b: TBytes;
begin
  s := '9660152e55a7178db9a9521cd80b7f4872f4be2290d1dd0f32205708f2e06589';

  s := TNetEncoding.Base64.Encode(s);

  // Above line produces:
  // OTY2MDE1MmU1NWE3MTc4ZGI5YTk1MjFjZDgwYjdmNDg3MmY0YmUyMjkwZDFkZDBmMzIyMDU3MDhmMmUwNjU4OQ==
  // which is not equal to:
  // lmAVLlWnF425qVIc2At/SHL0viKQ0d0PMiBXCPLgZYk=

end;

有一个StackOverflow question 面临同样的问题,我已经尝试了该问题的答案中的建议,但我仍然无法得出与 Amazon Scratchpad 相同的结果。具体来说:

SHA256 Scratchpad 显示的不是您使用 base64 转换的值。 您必须转换 SHA256 的十六进制值。

我花了整整 2 天的时间尝试了很多事情来获得正确的结果,从 Google 搜索结果中阅读了很多文章,但我仍然找不到答案。

请参阅我的其他相关问题,该问题显示了完整的 Delphi 代码,以及我面临的问题的完整描述: Delphi - Calculating Amazon MWS signature

谁能帮帮我!?

【问题讨论】:

    标签: delphi base64 amazon-mws delphi-10.2-tokyo


    【解决方案1】:

    那是因为您根本不了解Base64 的全部意义,包括如何正确编写它。它的主要目的是通过 7 位(即 ASCII)安全地传输 8 位数据(即整个字节):

    • 编码时采用 6 位并显示为一个字母。
    • 解码时取一个字母,还原6bit原始数据。

    这也是编码将大小膨胀 1/3 的原因。在电子邮件中发送附件时,前者存储在 Base64 中,因为电子邮件只有 7 位安全。这就是为什么发送 4 MiB 的大图最终会产生至少 5.2 MiB 的电子邮件。

    不,Base64 编码已经是 ASCII 并且是 7 位安全的东西是没有意义的。当有人想让他对文本9660152e55a7178db9a9521cd80b7f4872f4be2290d1dd0f32205708f2e06589 进行 Base64 编码时,每个人都应该警惕。

    您想要编码字节,而不是文本。您看到的是这些字节的十六进制表示。你实际上想要这个:

    var
      input: Array of Byte;
      output: String;
    begin
      SetLength( input, 32 );  // Represented in hexadecimal it would be a text of 64 characters
      input[0]:= $96;
      input[1]:= $60;
      input[2]:= $15;
      ...
      output:= TNetEncoding.Base64.Encode( input );
      if output<> 'lmAVLlWnF425qVIc2At/SHL0viKQ0d0PMiBXCPLgZYk=' then Halt();  // Expected output
    

    当只是尝试解码您期望的内容并直接查看它时,这一点更加明显:一次好像它是文本,一次是每个字符实际具有的字节值(因为您会发现它根本不是文本)。文本不是字节,反之亦然。这就是 Base64 存在的原因。不只是为了好玩。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-29
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 2018-06-04
      相关资源
      最近更新 更多