使用GO进行AWS SNS签名验证

时间:2013-11-16 05:04:06

标签: go verification sign amazon-sns

我想在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

谢谢!

1 个答案:

答案 0 :(得分:3)

我知道这是一个非常古老的问题,但我遇到了与记者相同的问题所以我花了一天的时间在AWS的协助下解决这个问题。我已将我的工作作为外部库开放,现在可用here

您可以像这样使用它(notificationJson是一个JSON字符串):

import (
  "encoding/json"
  "fmt"

  "github.com/robbiet480/go.sns"
)

var notificationPayload sns.Payload
err := json.Unmarshal([]byte(notificationJson), &notificationPayload)
if err != nil {
  fmt.Print(err)
}
verifyErr := notificationPayload.VerifyPayload()
if verifyErr != nil {
  fmt.Print(verifyErr)
}
fmt.Print("Payload is valid!")

感谢您对这个lazywei的初步工作,我将我的库基于您的上述代码!