我正在编写一个需要使用Dropbox的webhooks的程序。我还没有找到任何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
}
为了测试这个,我知道的唯一方法是使用Dropbox的this Python script。
Dropbox签名在HTTP头X-Dropbox-Signature
中以字符串形式发送。
为了将它与hmac.Equal
一起使用,您需要首先使用包encoding/hex将十六进制字符串表示解码为一个字节的片段。
import "encoding/hex"
[...]
hexSignature, err := hex.DecodeString(w.Signature)
[...]
然后您可以在比较中使用十六进制字节
[...]
// compare if it corresponds with the signature sent by DropBox
comparison := hmac.Equal(hexSignature, expectedMac)
[...]