Golang - Dropbox webhook 签名验证 hmac

Mar*_*Tro 1 sha256 go hmac webhooks dropbox-api

我正在编写一个需要使用 Dropbox 网络钩子的程序。我还没有找到任何已经到位的 Go 实现,所以我决定写我的。不幸的是,它似乎不起作用。

我认为这里的问题是hmac,因为我很可能做错了什么,但我似乎无法理解这里的问题到底在哪里。任何的想法?

以下是我所拥有的:

package dboxwebhook

import (
    "bytes"
    "crypto/hmac"
    "crypto/sha256"
    "errors"
    "io"
    "io/ioutil"
    "log"
)

type Signature struct {
    AppSecret []byte
    Signature []byte
}

func (w *Signature) Check(reqBody io.ReadCloser) error {

    if bytes.Compare(w.Signature, nil) == 0 {
        return errors.New("DropBox signature doesnt exist")
    }

    // building HMAC key (https://golang.org/pkg/crypto/hmac/)
    mac := hmac.New(sha256.New, w.AppSecret)
    requestBody, err := ioutil.ReadAll(reqBody)
    if err != nil {
        return err
    }

    mac.Write(requestBody)
    expectedMac := mac.Sum(nil)

    log.Println(w.AppSecret)
    log.Println(expectedMac)
    log.Println(w.Signature)

    // compare if it corresponds with the signature sent by DropBox
    comparison := hmac.Equal(w.Signature, expectedMac)

    if !comparison {
        return errors.New("Signature Check unsuccessful")
    }

    return nil

}
Run Code Online (Sandbox Code Playgroud)

为了测试这一点,我知道的唯一方法是使用Dropbox 中的这个 Python 脚本

小智 5

Dropbox 签名在 HTTP 标头中作为字符串发送X-Dropbox-Signature

为了将它与 一起使用hmac.Equal,您需要首先使用包encoding/hex将十六进制字符串表示解码为一个字节片。

    import "encoding/hex"

    [...]
    hexSignature, err := hex.DecodeString(w.Signature)
    [...]
Run Code Online (Sandbox Code Playgroud)

然后你可以在比较中使用十六进制字节

    [...]
    // compare if it corresponds with the signature sent by DropBox
    comparison := hmac.Equal(hexSignature, expectedMac)
    [...]
Run Code Online (Sandbox Code Playgroud)