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

如何在Elixir中生成HMAC字符串?,hmac,sha256,otp,elixir,amazon-product-api,Hmac,Sha256,Otp,Elixir,Amazon Product Api,我正在尝试用Elixir编写一个Amazon产品广告API客户端。《开发人员指南》介绍了必须使用请求和“机密访问密钥”创建HMAC-SHA26哈希的方法。这是我编写的用于处理请求签名的函数: defp sign_request(url) do url_parts = URI.parse(url) request = "GET\n" <> url_parts.host <> "\n" <> url_parts.path <> "\n" <

我正在尝试用Elixir编写一个Amazon产品广告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
defp签名请求(url)do
url\u parts=URI.parse(url)
request=“GET\n”url\u parts.host”\n“url\u parts.path”\n“url\u parts.query”
url“&Signature=“:crypto.hmac(:sha256,'ThisIsMySecretAccessKey',请求)
结束
传递到函数中的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
其二进制格式的返回基16整数时,您的问题可以这样解决:

:crypto.mac(:hmac, :sha256, "key", "The quick brown fox jumps over the lazy dog")
|> Base.encode16

这是来自

的匹配示例,或者可能使用Base.encode16(:crypto.hmac(:sha256,“key”,“敏捷的棕色狐狸跳过了懒狗”)|>Base.encode16)我使用了@sasajuri在其评论中提出的解决方案,因为它少了一行,更容易阅读。这与答案中的不同。差异与
hmac_字节|>Base.encode16
hmac_字节|>Base.encode16 |>Base.encode16
之间的差异相同。编码两次似乎不合适。这将是
:crypto.mac(:hmac,:sha256,priv_key,content)|>Base.encode16
,根据您可能还想研究在Elixir中使用字符串插值。可能会简化您的代码一点。