文档中心

签名机制

发送给KCS服务的HTTP请求中,必须包含授权参数和其他公共参数。KCS服务使用用户的Access Key ID和Secret Access Key进行加密方式来验证请求者身份。Access Key ID和Secret Access Key由金山云发给用户,Access Key ID作为用户的身份标识,Secret Access Key作为用户和服务器短进行签名计算的秘钥。

Http请求header中Authorization字段是服务的授权参数,其格式为:

Authorization="[HashMethod][空格]Credential=[access_key]/[scope],SignedHeaders=[signed_headers],Signature=[signature]"

其中:

[HashMethod] ="KSC4-HMAC-SHA256"
[access_key] =用户Access key ID
[scope] = [timestamp]/[region]/[service][req_type]

timestamp为yyyyMMdd格式的时间戳,region为请求服务所在区域名,service为访问的服务名,req_type为请求的类型。

[signed_headers]:将Headers按照name升序排列

[signed_headers] = [header_name_1];[header_name_2]....

签名算法:

[signature]=sha256(sha256(sha256(sha256(sha256("KSC4"+sign_key,timestamp),region),service),req_type),string_to_sign)

其中:

[sign_key] = 用户Secret Access Key

[stringToSign] = "KSC4-HMAC-SHA256" + "\n" + [X-Ksc-Date] + "\n" +[scope] + “\n” + SHA-256([canonical_request])

[canonical_request] = [HTTPRequestMethod] + "\n" + [CanonicalURI] + "\n" + [CanonicalQueryString] + "\n" + [CanonicalHeaders] + "\n" + [signed_headers] + "\n" + SHA-256([request_body])

[HTTPRequestMethod] = POST或GET

[CanonicalURI] = 请求URL中除去Endpoint之外的剩余部分。目前URL等于Endpoint,所以CanonicalURI为空

[CanonicalQueryString] = 空

[CanonicalHeaders]:按照[signed_headers]中的排序方式进行排序

[CanonicalHeaders] =

LowerCase (HeaderName1) + ‘:’ + Trim (HeaderValue1) + "\n"+LowerCase (HeaderName2) + ‘:’ + Trim (HeaderValue2) + "\n"+.......

[request_body] = Post 请求的body部分

Python签名代码

def canonical_request(self, http_request, sign_headers):
  cr = []
  r.append(http_request.method.upper())
  cr.append(self.canonical_uri(http_request))
  cr.append(self.canonical_query_string(http_request))
  headers_to_sign =self.headers_to_sign(http_request, sign_headers)
  cr.append(self.canonical_headers(headers_to_sign) + '\n')
  cr.append(self.signed_headers(headers_to_sign))
  if self.header_name_content_sha256 in http_request.headers:
    content_hash = self._ensure_bytes(http_request.headers[self.header_name_content_sha256])
    cr.append(content_hash)
  else:
    cr.append(self.payload(http_request))
  return '\n'.join(cr)
def string_to_sign(self, http_request, canonical_request, scope):
  sts = [self.hash_method]
  sts.append(http_request.headers[self.header_name_date])
  sts.append(scope)
  sts.append(sha256(canonical_request.encode('utf-8')).hexdigest())
  return '\n'.join(sts)
def _sign(self, key, msg, hex=False):
  key = self._ensure_bytes(key)
  if hex:
    sig = hmac.new(key, msg.encode('utf-8'), sha256).hexdigest()
  else:
    sig = hmac.new(key, msg.encode('utf-8'), sha256).digest()
  return si
def signature(self, string_to_sign, scope, secret_key):
  parts = scope.split('/')
  ts = parts[0]
  region = parts[1]
  service = parts[2]
  req_type = parts[3]
  k_date= self._sign((self.hash_keyword + secret_key).encode('utf-8'), ts)
  k_region = self._sign(k_date, region)
  k_service = self._sign(k_region, service)
  k_signing = self._sign(k_service, req_type)
  return self._sign(k_signing, string_to_sign, hex=True)