为保证 API 的安全调用,在调用 API 时阿里云会对每个 API 请求通过签名(Signature)进行身份验证。无论使用 HTTP 还是 HTTPS 协议提交请求,都需要在请求中包含签名信息。 概述 RPC API 要按以下格式在 API 请求的 Query 中增加签名(Signature)。
https://Endpoint/?SignatureVersion=1.0&SignatureMethod=HMAC-SHA1&Signature=xxxx%xxxx%3D&SignatureNonce=e7b1f31150be45594905ce6d28561286 其中: SignatureMethod:签名方式,目前支持 HMAC-SHA1。 SignatureVersion:签名算法版本,目前版本是 1.0。 SignatureNonce:唯一随机数,用于防止网络重放攻击。用户在不同请求间要使用不同的随机数值,建议使用通用唯一识别码(Universally Unique Identifier, UUID)。 Signature: 使用 AccessKey Secret 对请求进行对称加密后生成的签名。 签名算法遵循 RFC 2104 HMAC-SHA1 规范,使用 AccessSecret 对编码、排序后的整个请求串计算 HMAC值作为签名。签名的元素是请求自身的一些参数,由于每个 API 请求内容不同,所以签名的结果也不尽相同。可参考本文的操作步骤,计算签名值。
Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of( StringToSign)) ) 步骤一:构造待签名字符串 使用请求参数构造规范化的请求字符串(Canonicalized Query String)。 按照参数名称的字典顺序对请求中所有的请求参数(包括公共请求参数和接口的自定义参数,但不包括公共请求参数中的Signature 参数)进行排序。
说明 当使用 GET 方法提交请求时,这些参数就是请求 URI 中的参数部分,即 URI 中”?“之后由“&”连接的部分。 对排序之后的请求参数的名称和值分别用 UTF-8 字符集进行 URL 编码。编码规则请参考下表。
字符 编码方式 A-Z、a-z 和 0-9 以及”-”、“_”、“.”和“~” 不编码。 其它字符 编码成 %XY 的格式,其中 XY 是字符对应 ASCII 码的 16 进制表示。例如英文的双引号(””)对应的编码为 %22。 扩展的UTF-8字符 编码成 %XY%ZA…的格式。 英文空格 编码成 %20,而不是加号(+)。 该编码方式和一般采用的 application/x-www-form-urlencoded MIME 格式编码算法(例如 Java 标准库中的 java.net.URLEncoder的实现)存在区别。编码时可以先用标准库的方式进行编码,然后把编码后的字符串中的加号(+)替换成 %20,星号(*)替换成 %2A,%7E替换回波浪号(~),即可得到上述规则描述的编码字符串。本算法可以用下面的percentEncode方法来实现:
private static final String ENCODING = "UTF-8"; private static String percentEncode(String value) throws UnsupportedEncodingException { return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null; } 将编码后的参数名称和值用英文等号(=)进行连接。 将等号连接得到的参数组合按步骤 i 排好的顺序依次使用“&”符号连接,即得到规范化请求字符串。 将第一步构造的规范化字符串按照下面的规则构造成待签名的字符串。
StringToSign= HTTPMethod + “&” + percentEncode(“/”) + ”&” + percentEncode(CanonicalizedQueryString) 其中: HTTPMethod 是提交请求用的 HTTP 方法,例如 GET。 percentEncode(“/”) 是按照步骤 1.1 中描述的 URL 编码规则对字符 “/” 进行编码得到的值,即 %2F。 percentEncode(CanonicalizedQueryString) 是对步骤 1 中构造的规范化请求字符串按步骤 1.2 中描述的 URL 编码规则编码后得到的字符串。 步骤二:计算签名值 按照 RFC2104 的定义,计算待签名字符串(StringToSign)的 HMAC 值。
说明 计算签名时使用的 Key 就是您持有的 AccessKey Secret 并加上一个 “&” 字符(ASCII:38), 使用的哈希算法是 SHA1。 按照 Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值(Signature)。 将得到的签名值作为 Signature 参数添加到请求参数中。
说明 得到的签名值在作为最后的请求参数值提交时要和其它参数一样,按照 RFC3986 的规则进行 URL 编码。 示例 以 Listinstances API 为例,假设使用的 AccessKey Id 为 testid, AccessKey Secret 为 testsecret。 签名前的请求 URL 如下:
http://amqp-open.aliyuncs.com/?Timestamp=2020-02-11T06%3A00%3A10Z&Format=JSON&AccessKeyId=testid&Action=ListInstances&SignatureMethod=HMAC-SHA1&SignatureNonce=1e428a4d3e45bce88b2ed41cc34497eb&Version=2019-12-12&SignatureVersion=1.0 使用testsecret&,计算得到的签名值是:
xtC1HBet6MjHTQVZLo%2Fbm4dlJ0s%3D 最后将签名作为 Signature 参数加入到 URL 请求中,最后得到的 URL 为:
http://amqp-open.aliyuncs.com/?SignatureVersion=1.0&Action=ListInstances&Format=JSON&SignatureNonce=1e428a4d3e45b
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
涵盖 RocketMQ、Kafka、RabbitMQ、MQTT、轻量消息队列(原MNS) 的消息队列产品体系,全系产品 Serverless 化。RocketMQ 一站式学习:https://rocketmq.io/