HMAC-SHA签名流程

以腾讯上传用户在应用中的等级相关信息为例。接口详情在此【"http://wiki.open.qq.com/wiki/v3/user/get_info"】

在set_achievement这个接口中,接口参数包括openid, openkey, appid, pf, sig, user_attr, format

此接口最后的请求示例为

http://openapi.tencentyun.com/v3/user/set_achievement?
openid=B624064BA065E01CB73F835017FE96FA&
openkey=5F154D7D2751AEDC8527269006F290F70297B7E54667536C&
appid=2&
pf=qzone&
format=json&
user_attr=%7B%22level%22%3A10%7D&
sig=9999b41ad0b688530bb1b21c5957391c

这里除了sig其他参数都只是经过了URL编码而已,所以本文的重点也在如何生成sig。

点我查看详细签名规则

在写代码的过程中我们也可以思考下为什么需要生成签名~

Step 1. 构造源串

第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步中的字符串用&拼接起来。

Step 2. 构造密钥

得到密钥的方式:在应用的appkey末尾加上一个字节的“&”,即appkey&

Step 3. 生成签名

1. 使用HMAC-SHA1加密算法,使用Step2中得到的密钥对Step1中得到的源串加密。 (注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数。)

2. 然后将加密后的字符串经过Base64编码。 (注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数。)

3. 得到的签名值结果如下:

FdJkiDYwMj5Aj1UG2RUPc83iokk=

以下是生成sig的解决方案:

def getSig(cfg):
	strFilter = ".-_"
	codeUrlAddr = urllib2.quote(cfg[‘urlAddr‘],strFilter)
	urlData2 = sorted(cfg[‘urlData‘].iteritems(), key=lambda d:d[0])
	codeStr0 = ""
	for (value01,value02) in urlData2:
		if codeStr0:
			codeStr0 += "&" + str(value01) + ‘=‘ + str(value02)
		else:
			codeStr0 += str(value01) + ‘=‘ + str(value02)
	codeStr1 = urllib2.quote(codeStr0)
	codeConn = cfg[‘urlMethod‘] + ‘&‘ + codeUrlAddr + ‘&‘ + codeStr1
	sig = hmac.new(cfg[‘appkey‘] + ‘&‘, codeConn, hashlib.sha1).digest().encode(‘base64‘).rstrip()
	return sig

def test():
	urlData = {
		‘openid‘ : ‘12345‘,
		‘openkey‘ : ‘12345‘,
		‘pf‘ : ‘wanba_ts‘,
		‘appid‘ : 12345,
		‘format‘ : ‘json‘,
		‘user_attr‘ : ‘{"level":%d}‘ % 1234
	}
	urlcfg = {
		‘urlAddr‘ : ‘/v3/user/set_achievement‘,
		‘urlMethod‘ : ‘GET‘,
		‘appkey‘ : ‘ABCDWFSFFG‘,
		‘urlData‘ : urlData
	}
	urlData[‘sig‘] = getSig(urlcfg)
 

第一步:将请求的URI路径进行URL编码(URI不含host,URI示例:/v3/user/get_info)。

urlCfg中urlAddr是第一步中的请求的URI路径。

URL编码规则:

签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数。

十六进制数中字母必须为大写。

strFilter = ".-_" #不需要替换的字符
codeUrlAddr = urllib2.quote(cfg[‘urlAddr‘],strFilter)# url编码

第二步:将除“sig”外的所有参数按key进行字典升序排列。

urlData中就是第二步要求的sig参数外的所有参数,采用sorted方式进行排序。

urlData2 = sorted(cfg[‘urlData‘].iteritems(), key=lambda d:d[0])

第三步:将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。

codeStr0 = ""
    for (value01,value02) in urlData2:
        if codeStr0:
            codeStr0 += "&" + str(value01) + ‘=‘ + str(value02)
        else:
            codeStr0 += str(value01) + ‘=‘ + str(value02)
    codeStr1 = urllib2.quote(codeStr0)

当我看到urllib.urlencode可以用来直接生成&进行拼接的时候非常开心,但是后来发现它会对value进行url编码。这与我们的要求是不符合的。所以采用了上面这种诡异的方式。

第四步:将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。

codeConn = cfg[‘urlMethod‘] + ‘&‘ + codeUrlAddr + ‘&‘ + codeStr1

Step2和Step3

sig = hmac.new(cfg[‘appkey‘] + ‘&‘, codeConn, hashlib.sha1).digest().encode(‘base64‘).rstrip()

这样就得到了sig的值,文档看起来有些复杂,但是一步步做下来其实难度也不大。

接下来就是按照文档要求进行数据请求啦~

urlStr1 = urllib.urlencode(urlData)
 url = urlHost + qqUserInfos[‘getPlayzoneUserInfoUrl‘] + ‘?‘ + urlStr1

 request = urllib2.Request(url)
 result = json.loads(urllib2.urlopen(request).read())

在这个过程中不知道有没有小伙伴好奇为什么我的urlData里面的user_attr要像下面这样写

‘user_attr‘ : ‘{"level":%d}‘ % 1234

其实刚开始我是直接把{"level:1234}这个字典赋值给user_attr的。但是在操作的过程中发现由于python会把双引号自动变成单引号,导致生成的签名一直有问题。所以采用json格式来解决这个问题。

你以为本文这就完了?当!然!不!是!还有刚开始提出的问题没回答捏~

sooooo...为什么要生成签名

The answer is "为了确定数据来源正确合法"

双方如何根据签名确定数据来源正确,以腾讯为例:

1.腾讯给我们一个appkey用作密钥,我们按照腾讯约定的签名方式对sig以外的参数进行签名

2.生成签名后,将用作签名的参数和签名一起传给腾讯服务器。

3.服务器将签名与我们的appid对应的appkey进行解密。

4.将传递过去的参数排序,然后与生成的参数进行对比。若数据一致则能保证数据真实。

时间: 2024-11-05 07:42:59

HMAC-SHA签名流程的相关文章

一篇搞定RSA加密与SHA签名|与Java完全同步

看到这篇文章的同学可幸福了,当时在做RSA加密与签名的时候网上的资料简直不要太老,做完后实在是忍受不下去了,这篇文章我会详细讲解iOS如何实现RSA加密与签名,并且与Java完全同步,这是我的第二篇博客,若有什么不足之处还请大家指教. 基础知识 什么是RSA? 答:RSA是一种非对称加密算法,常用来对传输数据进行加密,配合上数字摘要算法,也可以进行文字签名. RSA加密中padding? 答:padding即填充方式,由于RSA加密算法中要加密的明文是要比模数小的,padding就是通过一些填充

漫谈iOS程序的证书和签名机制

原文:漫谈iOS程序的证书和签名机制 接触iOS开发半年,曾经也被这个主题坑的摸不着头脑,也在淘宝上买过企业证书签名这些服务,有大神都做了一个全自动的发布打包(不过此大神现在不卖企业证书了),甚是羡慕和崇拜.于是,花了一点时间去研究了一下iOS这套证书和签名机制,并撰文分享给需要的朋友.由于本人才疏学浅,多有遗漏或错误之处,还请大神多多指教. 非对称加密和摘要 非对称加密的特性和用法 非对称加密算法可能是世界上最重要的算法,它是当今电子商务等领域的基石.简而言之,非对称加密就是指加密密钥和解密密

Java加解密与签名

加密.数字签名基本概念: 加密: 密码常用术语: 明文,密文,加密,加密算法,加密秘钥,解密,解密算法,解密秘钥,密码分析:分析密文从而推断出明文或秘钥的过程主动攻击:入侵密码系统,采用伪造,修改,删除等手段向系统注入假消息进行欺骗.(对密文有破坏作用)被动攻击:对一个保密系统采取截获密文并对其进行分析和攻击.(对密文没有破坏作用)密码体制:由明文/密文/密钥空间,加密算法和解密算法五部分构成密码协议:也称安全协议,以密码学为基础的消息交换通信协议密码系统:指用于加密.解密的系统.柯克霍夫原则:

APP安全--网络传输安全 AES/RSA/ECC/MD5/SHA

移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在以下三类范畴当中. App代码安全,包括代码混淆,加密或者app加壳. App数据存储安全,主要指在磁盘做数据持久化的时候所做的加密. App网络传输安全,指对数据从客户端传输到Server中间过程的加密,防止网络世界当中其他节点对数据的窃听. 这一篇我们先聊下网络传输的安全. 安全相关的基础概念

Android签名机制之---签名过程具体解释

一.前言 又是过了好长时间,没写文章的双手都有点难受了.今天是圣诞节,还是得上班.由于前几天有一个之前的同事,在申请微信SDK的时候,遇到签名的问题,问了我一下,结果把我难倒了..我说Android中的签名大家都会熟悉的,就是为了安全,不让别人改动你的apk,可是我们真正的有了解多少呢?所以准备两篇文章好好介绍一下Android中签名机制. 在说道Android签名之前,我们须要了解的几个知识点 1.数据摘要(数据指纹).签名文件,证书文件 2.jarsign工具签名和signapk工具签名 3

[转载] Android签名机制之—签名过程详解

本文转载自: http://www.wjdiankong.cn/android%E7%AD%BE%E5%90%8D%E6%9C%BA%E5%88%B6%E4%B9%8B-%E7%AD%BE%E5%90%8D%E8%BF%87%E7%A8%8B%E8%AF%A6%E8%A7%A3/ 一.前言 又是过了好长时间,没写文章的双手都有点难受了.今天是圣诞节,还是得上班.因为前几天有一个之前的同事,在申请微信SDK的时候,遇到签名的问题,问了我一下,结果把我难倒了..我说Android中的签名大家都会熟悉

Android签名机制之---签名过程详解

一.前言 又是过了好长时间,没写文章的双手都有点难受了.今天是圣诞节,还是得上班.因为前几天有一个之前的同事,在申请微信SDK的时候,遇到签名的问题,问了我一下,结果把我难倒了..我说Android中的签名大家都会熟悉的,就是为了安全,不让别人修改你的apk,但是我们真正的有了解多少呢?所以准备两篇文章好好介绍一下Android中签名机制. 在说道Android签名之前,我们需要了解的几个知识点 1.数据摘要(数据指纹).签名文件,证书文件 2.jarsign工具签名和signapk工具签名 3

微信支付的开发流程

最近在公司做了微信支付的接入,这里总结下开发的一些经验 注意,我使用的是微信开放平台的支付,与手机app相关,而与公众账号无关.   微信支付的主要操作流程 1.用户浏览app,选定商品然后下单. 2.服务器处理订单逻辑,开始正式发起支付流程 3.首先,后台服务器向weixin服务器发起请求,获取一个token. 4.后台服务器拿到token,使用和其他参数加密,再次向weixin服务器发起请求,获取一个预支付prepayid 5.后台服务器将该prepayid返回给app客户端 6.app调用

atitit. 浏览器插件 控件 applet 的部署,签名总结 浏览器 插件 控件 的签名安全机制o9o

atitit. 浏览器插件 控件   applet 的部署,签名总结 浏览器 插件 控件 的签名安全机制o9o 1. 服务器部署签名 1 2. 签名流程::生成密钥..导出cert正书,签名 1 3. jarsigner 错误: java.lang.IllegalArgumentException: MALFORMED 1 4. Jar的包装and签名的流程原理 2 5. 参考 2 1. 服务器部署签名 applet 的本地调试,可以使用调整java.policy的解决...虽然中间也能正式版使