签名算法说明
签名算法说明
对于每一次HTTPS协议请求,我们会根据访问中的签名信息验证访问请求者身份。具体由使用appId和appSecret对称加密验证实现。
appSecret相当于用户密码,appId用于调用API,而用户密码用于登录CMP控制台 。其中appId是访问者身份,appSecret是加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密谨防泄露。
签名信息发送
签名信息通过HTTP头(x-ycs-security-authorization)随HTTP请求发送
签名信息格式
[Authorization:] [SIGN METHOD] [Credential=xxx],[SignedHeaders=xxx;xxx;xxx],[Signature=xxx]
签名信息分为5段,上面以[]分割,其中[]只是为了用以区别分割每段,前面两段以英文空格分割后面三段以英文的,字符分割
[Authorization:]
为固定格式字符串,注意大小写及使用英文:字符
[SIGN METHOD]
为签名算法的名称,目前只支持HMAC-SHA1,对应的算法名称为YCS1-HMAC-SHA1
[Credential=xxx]
=后面的xxx替换为用户的appId
[SignedHeaders=xxx;xxx;xxx]
=后面的为在签名签名算法中使用到的摘要信息在HTTP头中的名称,以英文;字符分割
[Signature=xxx]
=后面的xxx替换为签名字符串
签名信息生成算法
签名算法是通过请求的HTTP头中设置的参数和请求的包体生成签名的摘要,然后用appSecret作为秘钥对签名摘要进行签名算法加密的过程。签名字符串生成过程可以分为以下三个步骤:
1. 步骤 1. 确定摘要内容
生成签名字符串,首先需要确定签名的摘要内容,即确定通过哪些信息生成签名摘要。
摘要字段可以自定义,我们建议至少包含公共请求头中的x-ycs-requestid,x-ycs-timestamp字段。
摘要内容必须包含HTTP请求包体的内容,HTTP请求包体的内容作为requestBody参数参与签名
示例:
String signedHeaders="x-ycs-requestid;x-ycs-timestamp;x-my-header";
2. 步骤 2. 构造签名摘要
将所有签名内容名称按照字母序排序后,通过&连接key=value字符串组成签名摘要
示例:
Map<String, String> signParams = new HashMap<>();
String requestId = UUID.randomUUID().toString();
String timestamp = DateUtils.getISO8601Time(null);
String requestBody = "{\"name\":\"新建项目\",\"color\":\"project-color-1\"}";
signParams.put("x-ycs-requestid", requestId);
signParams.put("x-ycs-timestamp", timestamp);
signParams.put("x-my-header", "just add something");
signParams.put("requestBody", requestBody);
List<String> keys = new ArrayList<>(signParams.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
for(String key : keys) {
sb.append("&").append(key).append("=").append(signParams.get(key));
}
String signSummary = sb.toString().substring(1);
3. 步骤 3. 构造签名字符串
用appSecret作为秘钥加密签名摘要,生成签名字符串
示例:
String signature = Signers.getSigner(HmacSHA1Signer.NAME).sign(signSummary, appSecret);
String authorization = "Authorization: " + HmacSHA1Signer.NAME + " Credential=" + appId +",SignedHeaders="+signedHeaders+",Signature=" + signature;
创建项目JAVA代码完整示例
Map<String, String> signParams = new HashMap<>();
String signedHeaders="x-ycs-requestid;x-ycs-timestamp;x-my-header";
String appId = "10736709-63ca-401f-92ea-2e532045b8f0";
String appSecret = "e5dd6045-d369-11e8-88a8-fa163ebc68d3";
String requestId = UUID.randomUUID().toString();
String timestamp = DateUtils.getISO8601Time(null);
String requestBody = "{\"name\":\"新建项目\",\"color\":\"project-color-1\"}";
signParams.put("x-ycs-requestid", requestId);
signParams.put("x-ycs-timestamp", timestamp);
signParams.put("x-my-header", "just add something");
signParams.put("requestBody", requestBody);
List<String> keys = new ArrayList<>(signParams.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
for(String key : keys) {
sb.append("&").append(key).append("=").append(signParams.get(key));
}
String signSummary = sb.toString().substring(1);
String signature = Signers.getSigner(HmacSHA1Signer.NAME).sign(signSummary, appSecret);
String authorization = "Authorization: " + HmacSHA1Signer.NAME+" Credential=" + appId +",SignedHeaders="+signedHeaders+",Signature=" + signature;
HttpClient client = HttpClientBuilder.create().disableAuthCaching().disableRedirectHandling().disableAutomaticRetries().disableCookieManagement().build();
HttpPost post = new HttpPost("https://api.yovole.com/v1/project/create");
post.setHeader("x-ycs-requestid", requestId);
post.setHeader("x-ycs-timestamp", timestamp);
post.setHeader("x-my-header", signParams.get("x-my-header"));
post.setHeader("x-ycs-security-authorization", authorization);
post.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
String response = client.execute(post, new BasicResponseHandler());
创建项目Python代码完整示例
# -*- coding: utf-8 -*-
import base64
import datetime
import hmac
import json
import sys
import uuid
import requests
from hashlib import sha1
if __name__ == "__main__":
sign_params = dict()
app_id = "10736709-63ca-401f-92ea-2e532045b8f0"
app_secret = "e5dd6045-d369-11e8-88a8-fa163ebc68d3"
request_id = str(uuid.uuid1())
timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
param = {"name": "新建项目", "color": "project-color-1"}
request_body = json.dumps(param)
sign_params["x-ycs-requestid"] = request_id
sign_params["x-ycs-timestamp"] = timestamp
sign_params["requestBody"] = request_body
sign_summary = "&".join([(k + '=' + sign_params[k]) for k in sorted(sign_params.keys())])
if sys.version > '3':
hmac_code = hmac.new(app_secret.encode('utf-8'), sign_summary.encode('utf-8'), sha1).digest()
else:
hmac_code = hmac.new(app_secret.encode(), sign_summary.encode(), sha1).digest()
signature = base64.b64encode(hmac_code).decode()
authorization = "Authorization: %s Credential=%s,SignedHeaders=x-ycs-requestid;x-ycs-timestamp,Signature=%s" % ("YCS1-HMAC-SHA1", app_id, signature)
headers = dict()
headers["contentType"] = "application/json;charset=UTF-8"
headers["x-ycs-requestid"] = request_id
headers['x-ycs-timestamp'] = timestamp
headers["x-ycs-security-authorization"] = authorization
url = "https://api.yovole.com/v1/project/create"
r = requests.post(url, data=request_body, headers=headers, timeout=1000)
print(r.content)