如何在Elixir中生成HMAC字符串?

Zac*_*ood 11 elixir erlang-otp sha256 hmac amazon-product-api

我正在尝试在Elixir中编写Amazon Product Advertising API客户端.开发人员指南描述了签署API请求的过程,其中必须使用请求和"秘密访问密钥"创建HMAC-SHA26哈希.这是我写的用来处理签名请求的函数:

defp sign_request(url) do
  url_parts = URI.parse(url)
  request = "GET\n" <> url_parts.host <> "\n" <> url_parts.path <> "\n" <> url_parts.query
  url <> "&Signature=" <> :crypto.hmac(:sha256, 'ThisIsMySecretAccessKey', request)
end
Run Code Online (Sandbox Code Playgroud)

传递给函数的url看起来像这样: http://webservice.amazon.com/onca/xml?AssociateTag=ThisIsMyAssociateTag&AWSAccessKeyId=ThisIsMyAWSAccessKeyId&Keywords=stuff&Operation=ItemSearch&SearchIndex=Apparel&Service=AWSECommerceService&Timestamp=2014-11-22T12%3A00%3A00Z&Validate=True&Version=2013-08-01

我遇到的问题是,虽然:crypto.hmac/3返回二进制文件,但该二进制文件不是字符串; 通过返回值String.valid?/1回报false.因此,我无法将返回值连接到url字符串的末尾以对请求进行签名.

我使用:crypto.hmac/3不正确吗?有什么我想念的吗?我还有另一种方法吗?

Igo*_*kov 26

当您:crypto.hmac/3以二进制格式使用其返回基数为16的整数时,您的问题可以像这样解决:

:crypto.hmac(:sha256, "key", "The quick brown fox jumps over the lazy dog")
|> Base.encode16
Run Code Online (Sandbox Code Playgroud)

这是来自https://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29的匹配示例

  • 或者也许使用Base.encode16(:crypto.hmac(:sha256,"key","快速的棕色狐狸跳过懒狗")|> Base.encode16) (5认同)
  • 根据 https://erlang.org/doc/apps/crypto/new_api.html#the-,将来这将是 `:crypto.mac(:hmac, :sha256, priv_key, content) |&gt; Base.encode16`新API (5认同)
  • 这与答案中的内容不同.区别在于`hmac_bytes |> Base.encode16`和`hmac_bytes |> Base.encode16 |> Base.encode16`.编码两次似乎不合适. (4认同)