in example/http_authorization.go [53:150]
func authenticateWithHeaderMap(method, path string, headers map[string]string) bool {
// Get string to sign
var serviceHeaders []string
for k, v := range headers {
if strings.HasPrefix(strings.ToLower(k), "x-mns-") {
serviceHeaders = append(serviceHeaders, fmt.Sprintf("%s:%s", k, v))
}
}
sort.Strings(serviceHeaders)
serviceStr := strings.Join(serviceHeaders, "\n")
var signHeaderList []string
for _, key := range []string{"content-md5", "content-type", "date"} {
if val, ok := headers[key]; ok {
signHeaderList = append(signHeaderList, val)
} else {
signHeaderList = append(signHeaderList, "")
}
}
str2sign := fmt.Sprintf("%s\n%s\n%s\n%s", method, strings.Join(signHeaderList, "\n"), serviceStr, path)
fmt.Println("String to sign:", str2sign)
// 获取证书的URL
certURLBase64, ok := headers["x-mns-signing-cert-url"]
if !ok {
fmt.Println("x-mns-signing-cert-url Header not found")
return false
}
certURLBytes, err := base64.StdEncoding.DecodeString(certURLBase64)
if err != nil {
fmt.Println("Failed to decode base64 cert URL:", err)
return false
}
certURL := string(certURLBytes)
fmt.Println("x-mns-signing-cert-url:\t", certURL)
// 根据URL获取证书,并从证书中获取公钥
resp, err := http.Get(certURL)
if err != nil {
fmt.Println("Failed to fetch certificate:", err)
return false
}
//goland:noinspection GoUnhandledErrorResult
defer resp.Body.Close()
//goland:noinspection GoDeprecation
certData, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Failed to read certificate:", err)
return false
}
block, _ := pem.Decode(certData)
if block == nil || block.Type != "CERTIFICATE" {
fmt.Println("Failed to decode PEM block containing the certificate")
return false
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
fmt.Println("Failed to parse certificate:", err)
return false
}
pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
if !ok {
fmt.Println("Failed to cast public key to RSA public key")
return false
}
// 对Authorization字段做Base64解码
signatureBase64, ok := headers["authorization"]
if !ok {
fmt.Println("Authorization Header not found")
return false
}
signature, err := base64.StdEncoding.DecodeString(signatureBase64)
if err != nil {
fmt.Println("Failed to decode base64 signature:", err)
return false
}
// 认证
hash := sha1.New()
hash.Write([]byte(str2sign))
digest := hash.Sum(nil)
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA1, digest, signature)
if err != nil {
fmt.Println("Signature verification failed:", err)
return false
}
return true
}