Skip to content

签名算法说明

接口鉴权需要wps4签名的接口,header中需要携带以下字段:

参数参数类型是否必须说明
Content-Typestring固定为:“application/json”
Wps-Docs-Datestring取当前时间,格式:“Wed, 23 Jan 2013 06:43:08 GMT”
Wps-Docs-Authorizationstring签名值,格式:“WPS-4 accesskey”:Signature”

Wps-Docs-Authorization计算方法

接口签名时,只签uri字段,不签域名,具体计算规则如下:

Wps-Docs-Authorization:"WPS-4-GM $access_key:$Signature" 
Signature:hmac-sm3(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Docs-Date + sm3(HttpBody))

Ver + HttpMethod + URI + Content-Type + Wps-Docs-Date + sm3(HttpBody) 示例:

WPS-4-GMPOST/callback/path/demoapplication/jsonWed, 20 Apr 2022 01:33:07 GMTfc005f51a6e75586d2d5d078b657dxxxdf9c1dfa6a7c0c0ba38c715daeb6ede9
  • Ver: WPS-4-GM,表示算法版本,后续算法有更新,则变更该字段。
  • HttpMethod:表示HTTP 请求的Method的字符串,如PUT、GET、POST、HEAD、DELETE等。
  • URI:不带域名,如:"/api_url?app_id=aaaa"。
  • Content-Type:表示请求内容的类型,如:“application/json”。
  • Wps-Docs-Date:自行对签名时限进行验证。
  • HttpBody:如果为空,则sm3(body)部分取空串。

Go代码示例

const (
	Wps4GmDocsType             = "WPS-4-GM"
	DefaultContentTypeValue     = "application/json"
	ContentTypeHeaderKey       = "Content-Type"
	WpsDocsDateHeaderKey       = "Wps-Docs-Date"
	WpsDocsAuthHeaderKey       = "Wps-Docs-Authorization"
)


func (w *Wps4GmDocsAuth) Sign(r *http.Request) (*Wps4GmDocsHeader, error) {
	authorization := ""
	contentType := r.Header.Get(ContentTypeHeaderKey)
	date := r.Header.Get(WpsDocsDateHeaderKey)
	// 1. 计算content sm3值
	// HTTP Body中数据的sm3值十六进制表达方式
	// body为空时,则sm3(body部分取空串)
	body, err := ioutil.ReadAll(r.Body)
	r.Body = ioutil.NopCloser(bytes.NewReader(body))
	if err != nil {
		return nil, el.New(el.CodeAuthError, "sign fails: read body error", el.String(SignTypeKey, Wps4GmDocsType))
	}
	sm3Hex := ""
	if len(body) > 0 {
		s := sm3.New()
		s.Write(body)
		sm3Hex = hex.EncodeToString(s.Sum(nil))
	}
	// 2. 计算authorization
	mac := hmac.New(sm3.New, []byte(w.SecretKey))
	httpMethod := r.Method
	url := r.URL.RequestURI()
	mac.Write([]byte(Wps4GmDocsType + httpMethod + url + contentType + date + sm3Hex))
	macHex := hex.EncodeToString(mac.Sum(nil))
	authorization = Wps4GmDocsType + " " + w.AccessKey + ":" + macHex
	return &Wps4GmDocsHeader{
		ContentType:   contentType,
		Date:          date,
		Authorization: authorization,
	}, nil
}