3

我想在 GO 中实现 AWS SNS 签名验证。是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从上面的代码中得到。

谢谢!

4

1 回答 1

4

我知道这是一个很老的问题,但我和记者遇到了同样的问题,所以我花了一天时间在 AWS 的帮助下解决了这个问题。我已将我的工作作为外部库开源,现在可在此处获得。

你可以像这样使用它(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 上的初步工作,我的库基于您的上述代码!

于 2016-02-24T23:55:44.760 回答