apigw鉴权分析(1-2)腾讯开放平台 - 鉴权分析
一、访问入口
http://wiki.open.qq.com/wiki/%E8%85%BE%E8%AE%AF%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E7%AD%BE%E5%90%8D%E5%8F%82%E6%95%B0sig%E7%9A%84%E8%AF%B4%E6%98%8E

Step 1. 构造源串
源串是由3部分内容用“&”拼接起来的: HTTP请求方式 & urlencode(uri) & urlencode(a=x&b=y&...)
源串构造步骤如下:
第1步:将请求的URI路径进行URL编码(URI不含host,URI示例:/v3/user/get_info)。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。
第2步:将除“sig”外的所有参数按key进行字典升序排列。
注:除非OpenAPI文档中特别标注了某参数不参与签名,否则除sig外的所有参数都要参与签名。
第3步:将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。
第4步:将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。
注:Java_SDK_V3.0.6仅支持POST方式,如果用GET可能导致一直计算sig不正确。
源串构造示例如下
(由于是通用说明,这里以/v3/user/get_info作为示例,且示例中的请求串不可直接复制访问)
1. 原始请求信息:appkey:228bf094169a40a3bd188ba37ebe8723
HTTP请求方式:GET
请求的URI路径(不含HOST):/v3/user/get_info
请求参数:openid=11111111111111111&openkey=2222222222222222&appid=123456&pf=qzone&format=json&userip=112.90.139.30
2. 下面开始构造源串:
第1步:将请求的URI路径进行URL编码,得到: %2Fv3%2Fuser%2Fget_info
第2步:将除“sig”外的所有参数按key进行字典升序排列,排列结果为:appid,format,openid,openkey,pf,userip
第3步:将第2步中排序后的参数(key=value)用&拼接起来:
appid=123456&format=json&openid=11111111111111111&openkey=2222222222222222&pf=qzone&userip=112.90.139.30
然后进行URL编码( 编码时请关注URL编码注意事项,否则容易导致后面签名不能通过验证),编码结果为:
appid%3D123456%26format%3Djson%26openid%3D11111111111111111%26openkey%3D2222222222222222%26pf%3Dqzone%26
userip%3D112.90.139.30
第4步:将HTTP请求方式,第1步以及第3步中的到的字符串用&拼接起来,得到源串:
GET&%2Fv3%2Fuser%2Fget_info&appid%3D123456%26format%3Djson%26openid%3D11111111111111111%26
openkey%3D2222222222222222%26pf%3Dqzone%26userip%3D112.90.139.30
Step 2. 构造密钥
得到密钥的方式:在应用的appkey末尾加上一个字节的“&”,即appkey&,例如:
228bf094169a40a3bd188ba37ebe8723&
Step 3. 生成签名值
1. 使用HMAC-SHA1签名算法,使用Step2中得到的密钥对Step1中得到的源串签名。
(注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数。)
2. 然后将加密后的字符串经过Base64编码。
(注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数。)
3. 得到的签名值结果如下:
FdJkiDYwMj5Aj1UG2RUPc83iokk=
常见错误排障
为什么总是返回“-5:signature verification failed”?
签名校验失败分为以下两种情况:
1. sig参数生成错误
有可能由下列原因引起:
(1)构造源串时注意URI不含host,如/v3/user/get_info,而不是http://113.108.20.23/v3/user/get_info;
(2)构造源串时,没有将key排序后,再将(key=value)用&拼接起来。
(3)构造密钥时,没有将appkey后加“&”。
(4)某些语言的URLEncode系统方法在进行URL编码时,并没有按照现行的URL编码规则进行。详见下文的:URL编码注意事项。
对于支付和营销类接口,除了以上问题外,还有一些特别容易出错的地方:
(1)支付和营销相关回调协议中规定参数值都为string型,开发商出于本地记账等目的,对接收到的某些参数值先转为数值型再转为string型,导致字符串部分被截断(例如:字符串“13.14”转为整形再转为string 就会变成13),从而导致签名出错。
如果要进行本地记账等逻辑,建议用另外的变量来保存数值,传参时必须用原始接收到的string型值。
(2)支付和营销相关回调协议中,在进行签名生成时多加了一个步骤:
在构造源串的第3步“将排序后的参数(key=value)用&拼接起来,并进行URL编码”之前,需对value先进行一次编码 (编码规则为:除了 0~9 a~z A~Z !*() 之外其他字符按其ASCII码的十六进制加%进行表示,例如“-”编码为“%2D”)。
(3)支付和营销接口中的goodmeta参数,必须是UTF8格式,参与签名前要进行Base64编码。
(4)支付和营销接口中的payitem参数,含有*号字符,在进行URL编码时要注意观察是否进行了编码。
2. sig参数生成正确,但是参数传输前没有进行URL编码。
所有参数传输时都要进行URL编码,包括sig。如果没有进行URL编码,则即使sig是正确的,但是校验sig时不能匹配。
建议的解决方案:
(1)开发者可以使用平台提供的签名验证工具来计算签名:http://open.qq.com/tools , 通过工具吐出的签名生成过程,来排查具体是哪一步出了问题。
(2)如果您是PHP开发者,可以使用PHP SDK中的签名生成函数来生成签名,避免自己去进行复杂的签名生成逻辑的开发。
URL编码注意事项
URL编码规则:
签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数。
十六进制数中字母必须为大写。
注意事项:
1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,而不是%3D,导致加密签名通不过验证,请开发者注意检查。
2.Java 1.3和早期版本中,调用java.net.URLEncoder下的方法进行URL编码时,某些特殊字符并不会被编码,例如星号(*)。
由于URL编码规则中规定了星号(*)必须编码,因此在请求字符串中含星号(*)的情况下如果使用了上述方法,会导致生成的签名不能通过验证。
例如调用v3/pay/buy_goods接口时, payitem参数值中一定会含有* ,在使用类java.net.URLEncoder下的方法进行编码后,需开发人员手动将星号字符“*”替换为“%2A”,否则将导致加密签名一直通不过验证,请开发者注意检查。
3. 某些语言的urlencode方法会把“空格”编码为“+”,实际上应该编码为“%2B”。这也将生成错误的签名,导致签名通不过验证。
请开发者注意检查,手动将“+”替换为“%2B”。
在PHP中,推荐用rawurlencode方法进行URL编码。
二、鉴权方式分析
这里用的是签名算法!
开发者事先申请appId和appKey,访问时带上appId,使用appKey签名请求
服务端使用appId找到服务端的appKey,重新签名请求,进行比对。
算法:HMAC-SHA1签名算法
三、分解结论
apigw鉴权分析(1-2)腾讯开放平台 - 鉴权分析的更多相关文章
- apigw鉴权分析(1-4)新浪微博开放平台 - 鉴权分析
一.访问入口 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E 微博开放接口的调用,如 ...
- 开放平台鉴权以及OAuth2.0介绍
OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容. OAuth 2.0 ...
- QQ登录, 腾讯开放平台和QQ互联的坑
原文:QQ登录, 腾讯开放平台和QQ互联的坑 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012881042/article/details/7 ...
- 腾讯开放平台 手机QQ登录 错误码:110406 解决办法
作者:Panda Fang 出处:http://www.cnblogs.com/lonkiss/p/4204284.html 原创文章,转载请注明作者和出处,未经允许不可用于商业营利活动 腾讯开发平台 ...
- 如何在腾讯开放平台的云服务器上安装php和memcache 一
由于被通知腾讯的CEE要关闭了,必须自己切换到服务器,自己装php.烦到一个B. 首先找到官方wiki: http://wiki.qcloud.com/wiki/SUSE%E7%8E%AF%E5%A2 ...
- adobe air类app 接入腾讯开放平台移动游戏使用带tencent包名前缀的问题
作者:Panda Fang 出处:http://www.cnblogs.com/lonkiss/p/4209159.html 原创文章,转载请注明作者和出处,未经允许不可用于商业营利活动 ------ ...
- 腾讯开放平台web第三方登录获取信息类(包含签名)
不清楚具体参数的可以先看下第三方登录的文档: class QQ { //$appid 你的appid //$openid 获取到的唯一的用户openid //$openkey 获取到的openkey ...
- 腾讯开放平台 IOS应用URL schema、Boundle ID填写 (含微博、微信)
解释如下: qq比较麻烦点,需要两个 URL schemes 1.QQ+appID(appid原本是10进制的,需要转换16进制,网址:http://tool.oschina.net/hexconve ...
- 百度AI开放平台 情感倾向分析实例以及gbk编码解决
f=open('test.txt','a+',encoding='utf-8') for index,row in cxzg.iterrows(): text=str(row['text']) tex ...
随机推荐
- HashSet实现不重复储值原理-附源码解析
在HashSet中,基本的操作都是由HashMap底层实现的,因为HashSet底层是用HashMap存储数据.当向HashSet中添加元素的时候,首先计算元素的hashcode值,然后用这个(元素的 ...
- Java equals() 和hashCode()方法详解
Java的Object类中定义了equals方法,Object类中的equals方法源代码如下,从源代码中可以看出Object类中的equals方法是用来返回判断两个对象是否指向同一个对象(引用地址) ...
- 进入PE后不显示硬盘的解决办法
其实我很早之前就知道这个方法了,我虽然不知道原因,不过我是一个一个试出来的,转过来备忘, 内容介绍:经常使用PE的朋友相信都遇到过这样的问题,一些新购买的电脑可以正常把PE系统安装到U盘中,也可以正常 ...
- jq 抽奖转盘
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Online Judge(OJ)搭建——4、具体实现
代码编译.运行.保存: 本系统目前支持 Java.C++ 的编译.如有其他语言需要编译,扩展也很简单,因为这里使用了一个抽象类LanguageTest,处理好代码运行编译之前的文件保存,代码运行之中的 ...
- java 连接 elasticsearch 报错java.lang.NoClassDefFoundError: org/apache/http/auth/Credentials 解决
您的问题是您在应用程序类路径中缺少必需的JAR(这导致ClassNotFound异常).如果您下载了包含IP Camera驱动程序(webcam-capture-driver-ipcam-0.3.10 ...
- 笔记:Hibernate 拦截器和事件
Hibernate 在执行持久化的过程中,应用程序通常无法参与其中,通过事件框架,Hibernate 允许应用程序能响应特定的内部事件,从而允许实现某些通用的功能,或者对 Hibernate 进行扩展 ...
- BigDecimal 转成 double
NUMBER(20,2) 数据库里的字段number ,实体是BigDecimal 将BigDecimal转成double public double getOrderamount() { if ( ...
- SQL注入之Sqli-labs系列第一篇
在开始接触渗透测试开始,最初玩的最多的就是Sql注入,注入神器阿D.明小子.穿山甲等一切工具风靡至今.当初都是以日站为乐趣,从安全法实施后在没有任何授权的情况下,要想练手只能本地环境进行练手,对于sq ...
- Python 自学 之 String 常见操作
这是在Python 3.5.3版本下测试的.# Author Taylor_Manitoname ="my name is alex"#capitalized 大写的print(& ...