一个计算机技术爱好者与学习者

0%

支付宝签名与验签

1. 前言

支付宝提供了DSA、RSA、MD5三种签名方式,本文仅讨论RSA签名。

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

2. RSA理解

以下内容转载自21aspnet的《公钥,私钥和数字签名这样最好理解》,原作者举的例子通俗易懂,郝同学偷了过来,大家不要告诉他。

2.1. 公钥加密

假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥。
我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用
数字2,就是我的私钥,来解密。这样我就可以保护数据了。
我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,
只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。

2.2. 私钥签名

如果我用私钥加密一段数据(当然只有我可以用私钥加密,因为只有我知道2是我的私钥),结果所有的人都看到我的内容了,因为他们都知
道我的公钥是1,那么这种加密有什么用处呢?
但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他
解密看是不是c。他用我的公钥1解密,发现果然是c。
这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。
这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。

2.3. 小结

总结:公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。

3. 支付宝签名与验签

3.1. 请求参数签名

签名的目的:为了支付宝能够确定请求是由开发者发出的。

1、筛选
获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除sign与sign_type参数。

2、排序
将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。

3、拼接
将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。

4、签名
MD5签名的商户需要将key的值拼接在字符串后面,调用MD5算法生成sign;RSA签名的商户将待签名字符串和商户私钥带入SHA1算法中得出sign。

3.2. 返回参数验证签名

验签的目的:为了开发者能够确定请求是由支付宝发出的。

1、筛选
获取所有支付宝返回的参数,不包括字节类型参数,如文件、字节流。验签参数剔除sign与sign_type参数。

2、排序
将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。

3、拼接
将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。

4、验签
MD5:把MD5密钥(Key)拼接在待验证签名的字符串尾部,然后使用各自语言对应的MD5加密函数进行加密,得到的加密值与支付宝返回的参数sign做“相等”判断,同时对返回参数中的notify_id进行验证,如果这两个数据同时为true,则验证通过。

啊嘞,为什么没有RSA验签的说明?沈晨帅哥解释说,人家支付宝就只给你一种MD5!发送请求可选的签名方式有三种,接受请求只有一种签名方式,很合理。

3.3. 问题

假设支付宝返回参数的签名方式也是RSA,那么怎么验证签名?
猜测解:筛选、排序、拼接后,利用RSA公钥对待签名字符串进行加密,得到的加密值与支付宝返回的参数sign做“相等”判断,同时对返回参数中的notify_id进行验证,如果这两个数据同时为true,则验证通过。

前提是,对同一个字符串进行加密和签名,得到的sign是一样的!比如,利用公钥对“a”进行加密得到sign1,利用私钥对“a”进行签名得到sign2,那么,sign1=sign2!

那么,这个前提对不对呢?不好意思,不对!

公钥加密,通过私钥解密可以得到明文;私钥加密,通过公钥解密可以得到明文。然而,对于同一个字符串,公钥加密和私钥加密得到的密文是不同的!

3.4. 对称加密

对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密。

MD5加密算法就属于对称加密算法,因为无法进行解密,所以MD5加密算法也属于单向加密算法。常用于用户密码的存储和签名验签。

3.5. 非对称加密

不对称加密算法使用两把完全不同但又是完全匹配的一把钥匙——公钥和私钥。在使用不对称加密算法加密文件时,只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。

RSA加密算法就属于非对称加密算法,常用于加密解密和git服务器验签。

4. 书签

签名与验签

公钥,私钥和数字签名这样最好理解
http://blog.csdn.net/21aspnet/article/details/7249401

RSA算法原理(一)
http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html

RSA算法原理(二)
http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html