使用hmac在Elixir和PHP中生成签名

王志軍*_*王志軍 6 php elixir hmac

我尝试使用Elixir生成一个签名,它与PHP具有相同的值.

例如,PHP中的代码是

$signature = base64_encode(hash_hmac("sha256", "abc", "def"));
Run Code Online (Sandbox Code Playgroud)

并且输出将是

Mzk3ZjQ2NzM0MWU0ZDc4YzQ3NDg2N2VmMzI2MWNkYjQ2YzBlMTAzNTFlOWE5ODk5NjNlNmNiMmRjZTQwZWU1ZA==

我应该如何生成Elixir中具有相同值的签名.我试过下面的东西

iex(9)> :crypto.hmac(:sha256, "abc", "def") |> Base.encode64                          ?
"IOvA8JNERwE081BA9j6pix2OQUISlJ7lxQBCnRXqsIE="

iex(10)> :crypto.hash(:sha256, :crypto.hmac(:sha256, "abc", "def")) |> Base.encode64  ?
"dxGiPN6KqBJrtS2wlC4tnJXwUsWf4u1LPDtDFK+VT5A="
Run Code Online (Sandbox Code Playgroud)

或I开关的位置abcdef

iex(11)> :crypto.hash(:sha256, :crypto.hmac(:sha256, "def", "abc")) |> Base.encode64  ?
"b+3P5oHu8e6HIlJe2MzcGhKm7tCcF/NE5wPIbEhrFGU="

iex(12)> :crypto.hmac(:sha256, "def", "abc") |> Base.encode64                         ?
"OX9Gc0Hk14xHSGfvMmHNtGwOEDUempiZY+bLLc5A7l0="
Run Code Online (Sandbox Code Playgroud)

但它们都没有相同的价值.谁能告诉我如何以正确的方式做到这一点?

Dog*_*ert 4

主要问题是hash_hmac返回十六进制字符串,而:crypto.hmac返回二进制字符串。

Elixir 中的等效代码是:

iex(1)> :crypto.hmac(:sha256, "def", "abc") |> Base.encode16 |> String.downcase |> Base.encode64
"Mzk3ZjQ2NzM0MWU0ZDc4YzQ3NDg2N2VmMzI2MWNkYjQ2YzBlMTAzNTFlOWE5ODk5NjNlNmNiMmRjZTQwZWU1ZA=="
Run Code Online (Sandbox Code Playgroud)

我们需要使用String.downcase,因为Base.encode16返回大写的十六进制字符串A-F,而 PHPhash_hmac返回小写a-f

  • 查看文档后,我发现我可以像 `...|> Base.encode16(case: :lower) |> Base.encode64` 那样做,而不需要 `String.downcase` (4认同)