web签名验证程序【跨服务器、中文字符签名方法】-php为例
2010-10-18 20:03
519 查看
做电子商务网站,少不了接入支付。做开发同学知道,支付需要调试很多项,比较耗费时间,又有些挑战性的就是它的支付签名验证了。首先,我们看一下接口数字签名是怎么回事。
一、接口数字签名
甲方是:服务提供商,开方一个接口。getuserinfo.php,接收:coid(乙方的标示)username(用户名)调用接口,返回用户信息,这里只以二个字段说明。
乙方是:服务接口调用商,通过应用程序,调用甲方getuserinfo.php接口。
问题:甲方的接口是在互联网上面,对于所有公众都是可以访问的。但是他需要控制,访问接口用户是它授权的用户。
解决方案是:甲方加入一个签名字段,乙方调用时候必须将该字段传入。甲乙双方,通过一个私自定义的字串(私钥),加入到签名中。以上字段将变成:
这种,就是互联网上面,常见的接口的数字签名实例。coid,username任意改变,sign结果就会改变。甲方通过验证这个sign就能判断。数据是否是乙方传入的。因为:私钥key是除了他们知道,不会让第3方获得。这样就保证了接口安全。
一、接口数字签名
甲方是:服务提供商,开方一个接口。getuserinfo.php,接收:coid(乙方的标示)username(用户名)调用接口,返回用户信息,这里只以二个字段说明。
乙方是:服务接口调用商,通过应用程序,调用甲方getuserinfo.php接口。
问题:甲方的接口是在互联网上面,对于所有公众都是可以访问的。但是他需要控制,访问接口用户是它授权的用户。
解决方案是:甲方加入一个签名字段,乙方调用时候必须将该字段传入。甲乙双方,通过一个私自定义的字串(私钥),加入到签名中。以上字段将变成:
getuserinfo.php接口接收参数 | |
参数 | 说明 |
coid | 字符型,乙方的编号 |
username | 字符串,需要查询用户信息 |
sign | 数字签名,它的值是: md5(coid+username+key) |
甲乙双方私钥key是: |
二、md5签名中问题(中文验证不通过)
问题:
当coid,username都为字符串时候,双方签名都调试通过,后来发现username为中文了,签名不能通过。
这个问题是怎么样产生的呢?可能有的朋友,会跟对方进行操作,都用某个中文进行md5运算,发现得到结果不一致?
如是得出结果是:我们两个md5函数不标准,或者是不同语言下,md5函数计算结果不一样。呵呵,这个结论得出后,就认为签名不能通过了。于是乎,有个同学,在自己电脑里面安装几个程序,进行md5中文签名,发现得到结果一样。
分析,继续思考……
结果:发现这几个程序所使用编码都一致,所以中文签名结果一样的。
终于发现问题了:签名不一致是由于程序的字符编码不一致原因。如果大家看了:
md5函数:以传入字节码为内容进行签名验证。因此,需要签名结果一致,只需要传入参数字节码是相同的,那么md5签名结果就相同。
相同汉字不同字节码:
以下以汉字“中”为例:
gb2312字节码是:D6D0
utf-8字节码是:E4B8AD
在2个程序里面,默认字符集不同,看是都是相同中文,md5结果自然就不同了。
三、web通讯中签名怎么样做?
还是以上面为例:
甲方:程序是utf-8编码
乙方:程序是gb2312编码
通过流程我们很轻易知道,做sign验证时候,甲方在获得变量时候就进行,如:
乙方代码:(test.php保存时保存为:gb2312编码或ansi或gbk)
甲方代码:(test2.php保存时候选择:utf-8)