为保证API的安全调用,在调用API时公交云会对每个API请求通过签名进行身份验证。即无论使用HTTP还是HTTPS协议提交请求,都需要在请求中包含签名(Signature)信息。
一、概述
REST API需要按如下格式在API请求的Header中添加Authorization头来签名:
Authorization:ptcs AccessKeyId:Singature
其中:
ptcs:Public Transport Cloud Service的缩写,固定标识不可修改。
AccessKeyId:用户调用API所用的密钥ID。密钥ID和其对应的AccessSecret由服务端分配给客户端。
Signature:使用AccessKey Secret对请求进行对称加密的签名。
二、计算签名
按照RFC2104的定义,使用AccessSecret对编码、排序后的整个请求串计算HMAC值作为签名。
Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(
StringToSign) ) )
签名算法遵循RFC2104 HMAC-SHA1规范,签名的元素是请求自身的参数,由于每个API请求内容不同,所以签名的结果也不尽相同。
1. 构建待签名字符串
待签名字符串(StringToSign)是API请求拼装的字符串,用于计算签名,包含:
HTTP协议Header
公交云协议Header (CanonicalizedHeaders)
规范资源(CanonicalizedResource)
Body
待签名字符串必须按照以下顺序构造:
StringToSign =
//http协议Header
HTTP-Verb + "\n" +
Accept + "\n" +
Content-MD5 + "\n" +//Body的MD5值放在此处
Content-Type + "\n" +
Date + "\n" +
//公交云协议header(CanonicalizedHeaders)
CanonicalizedHeaders +
//签名中如何包含CanonicalizedResource(规范资源)
CanonicalizedResource
示例:原始请求
1. POST /stacks?name=test_alert&status=COMPLETE HTTP/1.1
2. Host: ***.ptcs.com
3. Accept: application/json
4. Content-MD5: ChDfdfwC+Tn874znq7Dw7Q==
5. Content-Type: application/x-www-form-urlencoded;charset=utf-8
6. Date: Fri Oct 12 10:00:00 GMT+08:00 2018
7. x-ptcs-signature-nonce: 550e8400-e29b-41d4-a716-446655440000
8. x-ptcs-signature-method: HMAC-SHA1
9. x-ptcs-signature-version: 1.0
10. x-ptcs-version: v1
示例:规范请求
1. POST
2. application/json
3. ChDfdfwC+Tn874znq7Dw7Q==
4. application/x-www-form-urlencoded;charset=utf-8
5. Fri Oct 12 10:00:00 GMT+08:00 2018
6. x-ptcs-signature-nonce: 550e8400-e29b-41d4-a716-446655440000
7. x-ptcs-signature-method:HMAC-SHA1
8. x-ptcs-signature-version:1.0
9. x-ptcs-version:v1
10. /stacks?name=test_alert&status=COMPLETE
HTTP协议Header
计算签名必须包含参数:Accept、Content-MD5、Content-Type、Date的值(不包含key),并按字典顺序排列;若值不存在则以“\n”补齐。
示例:原始header
Accept: application/json
Content-MD5: ChDfdfwC+Tn874znq7Dw7Q==
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Date: Fri Oct 12 10:00:00 GMT+08:00 2018
示例:规范header
application/json
ChDfdfwC+Tn874znq7Dw7Q==
application/x-www-form-urlencoded;charset=utf-8
Fri Oct 12 10:00:00 GMT+08:00 2018
公交云协议Header (CanonicalizedHeaders)
公交云规范头,非标准HTTP头部信息,是请求中出现的以x-ptcs-为前缀的参数。请求中必须包含:
将所有的头和内容用“\n”分隔符分隔拼成最后的CanonicalizedHeaders。
示例:原始Header
x-ptcs-signature-nonce: 550e8400-e29b-41d4-a716-446655440000
x-ptcs-signature-method: HMAC-SHA1
x-ptcs-signature-version: 1.0
x-ptcs-version: v1
示例:规范header(只取协议Header头的value)
550e8400-e29b-41d4-a716-446655440000
HMAC-SHA1
1.0
v1
规范资源(CanonicalizedResource)
CanonicalizedResource表示想要访问资源的规范描述,需要将子资源和query参数一同按照字典序,从小到大排列并以“&”为分隔符生成子资源字符串(?后的所有参数)。
示例:原始请求
/stacks?status=COMPLETE&name=test_alert
示例:规范请求(只取问号后面的请求参数)
name=test_alert&status=COMPLETE
Body
将请求的body用MD5算法加密,在进行base64编码,将结果添加到Content-MD5中。如果body内容为空,则Content-MD5的值也为空。
2. 将签名放入请求
将计算好的签名以如下格式添加到请求的Header中:
Authorization: ptcs AccessKeyId:Signature
三、防止重放攻击
Date:发起请求的时间,可以取自机器的本地实现。当服务端收到请求时,会校验这个参数的有效性,误差不超过15分钟。
x-ptcs-signature-nonce:这个是请求的唯一标识,一般使用UUID来标识。服务端收到这个参数后会校验这个参数的有效性,同样的值,15分内只能被使用一次。
四、举例
签名原始字符串:
POST
application/json
ChDfdfwC+Tn874znq7Dw7Q==
application/json
Fri Oct 12 10:00:00 GMT+08:00 2018
BK70J6ChwnGCyq9r
HMAC-SHA1
1.0
v1
cityCode=330100&planId=50690
消息头内容,以postman为例: