我想在GO中实施AWS SNS签名验证。 Here是AWS提供的签名验证教程。
然而,有些观点我无法理解。
7:生成Amazon SNS消息的派生哈希值。以规范格式将Amazon SNS消息提交给用于生成签名的相同哈希函数。
如何派生哈希值?我应该使用哪种哈希函数?
8:生成Amazon SNS消息的断言哈希值。断言的哈希值是使用公钥值(来自步骤3)解密随Amazon SNS消息传递的签名的结果。
如何获取声明的哈希值?
这是我的代码,我有一个结构通知:
type Notification struct {
Message string
MessageId string
Signature string
SignatureVersion string
SigningCertURL string
SubscribeURL string
Subject string
Timestamp string
TopicArn string
Type string
UnsubscribeURL string
}
我已经生成了规范字符串:
signString := fmt.Sprintf(`Message
%v
MessageId
%v`, self.Message, self.MessageId)
if self.Subject != "" {
signString = signString + fmt.Sprintf(`
Subject
%v`, self.Subject)
}
signString = signString + fmt.Sprintf(`
Timestamp
%v
TopicArn
%v
Type
%v`, self.Timestamp, self.TopicArn, self.Type)
从base64解码签名
signed, err := base64.StdEncoding.DecodeString(self.Signature)
从.pem获取证书
resp, _ := http.Get(self.SigningCertURL)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
p, _ := pem.Decode(body)
cert, err := x509.ParseCertificate(p.Bytes)
现在,如何使用规范字符串验证签名?以下代码是否正确?
cert.CheckSignature(x509.SHA1WithRSA, signed, []byte(signString))
我总是从上面的代码中获得crypto/rsa: verification error
。
谢谢!
答案 0 :(得分:3)
我知道这是一个非常古老的问题,但我遇到了与记者相同的问题所以我花了一天的时间在AWS的协助下解决这个问题。我已将我的工作作为外部库开放,现在可用here。
您可以像这样使用它(notificationJson是一个JSON字符串):
import (
"encoding/json"
"fmt"
"github.com/robbiet480/go.sns"
)
var notificationPayload sns.Payload
err := json.Unmarshal([]byte(notificationJson), ¬ificationPayload)
if err != nil {
fmt.Print(err)
}
verifyErr := notificationPayload.VerifyPayload()
if verifyErr != nil {
fmt.Print(verifyErr)
}
fmt.Print("Payload is valid!")
感谢您对这个lazywei的初步工作,我将我的库基于您的上述代码!