预期 MAC 不同于从 NodeJS 到 Go 服务器的传入

Expected MAC different than incoming one from NodeJS to Go server

我在尝试在我的 NodeJS 和 Go 服务器之间实现 HMAC 时遇到问题。现在,从我的 Go 服务器生成的预期 MAC 与来自我的 NodeJS 服务器的实际 MAC 不同。

// NodeJS generated MAC
const generateMAC = (message, secret) => {
  return crypto.createHmac('sha256', secret).update(message).digest('hex');
};

req.headers['blocklist-auth'] = generateMAC(
  JSON.stringify(req.body),
  secret
);

Go HMAC 验证(从 NodeJS 接收 MAC 并尝试 tp 验证)

func generateMAC(message []byte, secret []byte) []byte {
    mac := hmac.New(sha256.New, secret)
    _, err := mac.Write(message)
    if err != nil {
        return nil
    }
    s := mac.Sum(nil)
    return s
}

// ValidMAC reports whether messageMAC is a valid HMAC tag for message.
func validMAC(message []byte, messageMAC []byte, secret []byte) bool {
    expectedMAC := generateMAC(message, secret)
    log.Infof("E: %s -- M: %s", string(expectedMAC), string(messageMAC), )
    return hmac.Equal(messageMAC, expectedMAC)
}

调试后,我记录了预期的 MAC 和实际的 MAC 的样子

预计: n\ufffd\ufffdmi\u0015\ufffd|\ufffdE\ufffd\ufffd>\ufffd\u000e0\u0012C1\ufffd\ufffd\ufffds?!\u001a|\ufffdH<!

实际:

55d31eb5caf5f5046d054fcf39721ba273cd97da66f663f8337e10ac62045197

我注意到预期和实际 MAC 之间的长度也不同。来自 NodeJS 的长度是预期 MAC 的两倍。不知道为什么。

它们似乎产生相同的结果,但您传递给节点代码中的摘要调用的编码是 'hex'。 如果在两端以相同的方式编码 return,它们应该匹配。

const crypto = require('crypto')
const generateMAC = (message, secret) =>
  crypto.createHmac('sha256', secret).update(message).digest('base64')
console.log(generateMAC('foo', 'bar'))
package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
)

func generateMAC(message []byte, secret []byte) string {
    mac := hmac.New(sha256.New, secret)
    _, err := mac.Write(message)
    if err != nil {
        return "oh no"
    }
    return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

func main() {
    fmt.Println(generateMAC([]byte("foo"), []byte("bar")))
}

这两个都产生相同的输出,因为它们都编码为 base64:FHkzIYqqvAuLEKKzpcNGhMjZQ0G88QpHNtxycPd0GFE=.

.digest() return如果未指定编码,默认情况下是一个缓冲区,然后您也可以使用 these encodings 之一在单独的 .toString() 中使用它。