签名方法 v1
申请安全凭证
云协作OpenAPI使用的安全凭证为密钥对,包含SecretId
和SecretKey
。每个组织可拥有五对密钥。
SecretId
:用于标识API调用者身份SecretKey
:用于验证API调用者的身份- 请妥善保管密钥,如泄漏,可能导致数据安全问题。如果已发现泄漏,可以在管理后台禁用此安全凭证。
申请安全凭证
- 方法一:登录云协作OpenAPI管理后台,自助申请
- 方法二:联系管理员申请
生成签名串
有了安全凭证SecretId
和 SecretKey
后,就可以生成签名串了。以下是使用签名方法 v1 生成签名串的详细过程:
假设用户的 SecretId
和 SecretKey
分别是:
- SecretId: fb79c2cdcd9840a03ae456595c5df34b
- SecretKey: 9a7325dd8afb9cdd2ab4bb7b83bb1ab2
注意:这里只是示例,请根据用户实际申请的 SecretId 和 SecretKey 进行后续操作!
以查询群成员列表(/api/open/group-member/list)为例,当用户调用这一接口时,其请求参数可能如下:
- 公共参数(Header)
参数名称 | 类型 | 必选 | 描述 |
---|---|---|---|
X-YNOTE-Timestamp | Long | 是 | 1663731166000 |
X-YNOTE-Nonce | Long | 是 | 12 |
X-YNOTE-Version | String | 是 | 2022-10-01 |
Authorization | String | 是 | 认证头 |
- 请求参数
参数名称 | 中文 | 参数值 |
---|---|---|
groupId | 群ID | 139849950 |
2.1. 请求参数编码
使用UTF-8字符集按照 RFC3986 规则编码请求参数和参数取值,编码规则如下:
- 对于字符A ~ Z、a ~ z、0 ~ 9以及字符-、_、.和~不编码。
- 对于其他字符编码成%XY的格式,其中XY是字符对应ASCII码的16进制(大写)。
不同语言实现的URLEncode方式不同,为了得到 RFC3986 规则的编码,分别说明如下:
- 如果您使用的是Java中的java.net.URLEncoder,可以先用URLEncoder.encode方法编码,随后将编码后的字符中加号(+)替换为%20、星号(*)替换为%2A、%7E替换为波浪号(~)即可;
- 如果您使用的是golang中的net/url,可以用url.Values.Encode方法编码,随后将编码后的字符中加号(+)替换为%20即可;
- 如果您使用的是php中的rawurlencode方法,不需要替换;
- 如果您使用的是python3中的urllib.request,可以用urllib.request.quote方法,需要指定字符串中的波浪号(~)不编码,例如urllib.request.quote(str, ‘~’),str为待编码字符串;
注意:
- header中的公共参数不需要Encode
- 文件参数不参与签名计算
2.2. 对参数排序
将公共头(X-YNOTE-Timestamp
、X-YNOTE-Nonce
、X-YNOTE-Version
)与参数(groupId
)按照Unicode顺序升序排列(字符完全匹配,则长度更长着更大)。
注意:
1)只按参数名进行排序,参数值保持对应即可,不参与比大小;
2)按 ASCII 码比大小,如 InstanceIds.2 要排在 InstanceIds.12 后面,不是按字母表,也不是按数值。上述示例参数的排序结果如下:
{ 'X-YNOTE-Nonce' : 12, 'X-YNOTE-Timestamp' : 1663731166000, 'X-YNOTE-Version' : '2022-10-01','groupId' : 139849950 }
使用其它程序设计语言开发时,可对上面示例中的参数进行排序,得到的结果一致即可。
2.3. 拼接请求字符串
此步骤生成请求字符串。
将把上一步排序好的请求参数格式化成“参数名称=参数值”的形式,如对 groupId 参数,其参数名称为 "groupId" ,参数值为 "139849950" ,因此格式化后就为 groupId=139849950 。
然后将格式化后的各个参数用"&"拼接在一起,最终生成的请求字符串为:
X-YNOTE-Nonce=12&X-YNOTE-Timestamp=1663731166000&X-YNOTE-Version=2022-10-01&groupId=139849950
2.3. 拼接签名原文字符串
此步骤生成签名原文字符串。
签名原文字符串由以下几个参数构成:
- 请求方法: 支持 POST 和 GET 方式,这里使用 GET 请求,注意方法为全大写。
- 请求路径: 当前版本云API的请求路径固定为 /api/open/group-member/list 。
- 请求字符串: 即上一步生成的请求字符串。
签名原文串的拼接规则为:请求方法 +请求路径 + ? + 请求字符串。
示例的拼接结果为:
GET/api/open/group-member/list?X-YNOTE-Nonce=12&X-YNOTE-Timestamp=1663731166000&X-YNOTE-Version=2022-10-01&groupId=139849950
2.4. 生成签名串
此步骤生成签名串。
首先使用 HMAC-SHA256 算法对上一步中获得的签名原文字符串进行签名,然后将签名后的二进制哈希值结果以16进制编码输出得出结果。
具体代码如下,以 Java 语言为例:
new HmacUtils(HmacAlgorithms.HMAC_SHA_256, "9a7325dd8afb9cdd2ab4bb7b83bb1ab2")
.hmacHex("GET/api/open/group-member/list?X-YNOTE-Nonce=12&X-YNOTE-Timestamp=1663731166000&X-YNOTE-Version=2022-10-01&groupId=139849950"));
最终得到的签名串为:
06ba1741fd2bf555a29e598d06e14092a132072b41ede95b1048f8717d07d1a5
使用其它程序设计语言开发时,可用上面示例中的原文进行签名验证,得到的签名串与例子中的一致即可。
签名串编码
生成的签名串并不能直接作为请求参数,需要将其组装为Authorization认证头,认证头格式如下:
Authorization =
Algorithm + ' ' +
'Credential=' + SecretId + '/' + CredentialScope + ',' +
'Signature=' + Signature
字段名称 | 解释 |
---|---|
Algorithm | 签名方法,固定为 YNOTE-HMAC-SHA256-V1 。 |
SecretId | 密钥对中的 SecretId,即 fb79c2cdcd9840a03ae456595c5df34b 。 |
CredentialScope | 见上文,凭证范围。此示例计算结果是 2022-09-21/yxz/ynote_request 。 |
Signature | 签名值。此示例计算结果是 06ba1741fd2bf555a29e598d06e14092a132072b41ede95b1048f8717d07d1a5。 |