英文:
AWS SNS signature verification with GO
问题
我想在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
错误。
谢谢!
英文:
I want to implement AWS SNS signature verification in GO. Here is the signature verification tutorial provided by AWS.
However, there are some points I can not get it.
> 7: Generate the derived hash value of the Amazon SNS message. Submit the Amazon SNS message, in canonical format, to the same hash function used to generate the signature.
How to derived the hash value? Which hash function should I use?
> 8: Generate the asserted hash value of the Amazon SNS message. The asserted hash value is the result of using the public key value (from step 3) to decrypt the signature delivered with the Amazon SNS message.
How to get the asserted hash value?
Here is my code, I have a struct for notification:
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
}
and I've already generated the canonical 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)
Decode signature from base64
signed, err := base64.StdEncoding.DecodeString(self.Signature)
Get the certificate from .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)
Now, how can I verify the signature with my canonical string? Is the following code right?
cert.CheckSignature(x509.SHA1WithRSA, signed, []byte(signString))
I always get crypto/rsa: verification error
from above code.
Thanks!
答案1
得分: 4
我知道这是一个很旧的问题,但我遇到了与报告者相同的问题,所以花了一天的时间在AWS的帮助下解决了这个问题。我已经将我的工作作为一个外部库开源,现在可以在这里找到。
你可以像这样使用它(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的初步工作,我基于你上面的代码开发了我的库!
英文:
I know this is a really old question, but I had the same problems as the reporter so I took a day to figure this out with the assistance of AWS. I have open sourced my work as an external library, now available here.
You can use it like this (notificationJson is a JSON string):
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!")
Thanks for your initial work on this lazywei, I based my library on your above code!
答案2
得分: 0
在关于Amazon SNS消息签名验证的讨论中,还需要注意到Amazon SNS现在支持基于SHA256哈希的消息签名:
这是发布博客文章:
英文:
In the context of this discussion about Amazon SNS message signature verification, it’s also important to notice that Amazon SNS now supports message signatures based on SHA256 hashing:
Here's the launch blog post:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论