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!