英文:
Golang - Dropbox webhook signature validation hmac
问题
我正在编写一个需要使用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的这个Python脚本。
英文:
I am writing a program that needs to use Dropbox's webhooks. I haven't been able to find any Go implementation already in place, so I've decided to write mine. Unfortunately, it doesn't seem to work.
I think the issue here is with hmac, as I am most probably doing something wrong, but I just can't seem to understand where exactly the issue here. Any idea?
The following is what I have:
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
}
To test this, the only way I know is to use this Python script from Dropbox.
答案1
得分: 5
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)
[...]
英文:
The Dropbox signature is sent as string in the HTTP header X-Dropbox-Signature
.
So as to use it with hmac.Equal
, you need to decode the hex string representation to a slice of byte first using package encoding/hex.
import "encoding/hex"
[...]
hexSignature, err := hex.DecodeString(w.Signature)
[...]
Then you can use the hex bytes in the comparison
[...]
// compare if it corresponds with the signature sent by DropBox
comparison := hmac.Equal(hexSignature, expectedMac)
[...]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论