设为首页 收藏本站
查看: 867|回复: 0

[经验分享] web签名验证程序【跨服务器、中文字符签名方法】-php为例

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-8-30 11:54:31 | 显示全部楼层 |阅读模式
  做电子商务网站,少不了接入支付。做开发同学知道,支付需要调试很多项,比较耗费时间,又有些挑战性的就是它的支付签名验证了。 首先,我们看一下接口数字签名是怎么回事。
  
  一、接口数字签名

  甲方是:服务提供商,开方一个接口。getuserinfo.php ,接收:coid(乙方的标示) username(用户名) 调用接口,返回用户信息,这里只以二个字段说明。
  
  乙方是:服务接口调用商,通过应用程序,调用甲方getuserinfo.php 接口。
  
  问题:甲方的接口是在互联网上面,对于所有公众都是可以访问的。但是他需要控制,访问接口用户是它授权的用户。
  解决方案是:甲方加入一个签名字段,乙方调用时候必须将该字段传入。甲乙双方,通过一个私自定义的字串(私钥),加入到签名中。以上字段将变成:
  

getuserinfo.php接口接收参数
参数说明
coid字符型,乙方的编号
username字符串,需要查询用户信息
sign  数字签名,它的值是:
  md5(coid+username+key)

甲乙双方私钥key是:asdf@#%#%#%
  
  这种,就是互联网上面,常见的接口的数字签名 实例。 coid,username任意改变,sign结果就会改变。甲方通过验证这个sign就能判断。数据是否是乙方传入的。因为:私钥key 是除了他们知道,不会让第3方获得。 这样就保证了接口安全。

  二、md5签名中问题(中文验证不通过)

  问题:
  当coid,username都为字符串时候,双方签名都调试通过,后来发现username 为中文了,签名不能通过。
  这个问题是怎么样产生的呢?可能有的朋友,会跟对方进行操作,都用某个中文进行md5运算,发现得到结果不一致?
  如是得出结果是:我们两个md5函数不标准,或者是不同语言下,md5函数计算结果不一样。 呵呵,这个结论得出后,就认为签名不能通过了。 于是乎,有个同学,在自己电脑里面安装几个程序,进行md5中文签名,发现得到结果一样。
  分析,继续思考……
  结果:发现这几个程序所使用编码都一致,所以中文签名结果一样的。
  终于发现问题了:签名不一致是由于程序的字符编码不一致原因。 如果大家看了:web 程序乱码深入分析【基础原理篇】--php为例 可能就知道该怎么做了。 这里我先说明下签名函数md5是怎么样处理的。
  md5函数:以传入字节码为内容进行签名验证。因此,需要签名结果一致,只需要传入参数字节码是相同的,那么md5签名结果就相同。
  
  相同汉字不同字节码:
  以下以汉字“中”为例:
  gb2312 字节码是:D6D0
  utf-8    字节码是:E4B8AD
  在2个程序里面,默认字符集不同,看是都是相同中文,md5结果自然就不同了。

  三、web通讯中签名怎么样做?

  还是以上面为例:
  甲方:程序是utf-8编码
  乙方:程序是gb2312编码
DSC0000.png
  通过流程我们很轻易知道,做sign验证时候,甲方在获得变量时候就进行,如:
  乙方代码:(test.php 保存时保存为:gb2312编码或ansi或gbk)

<?php
header("Content-type:text/html;charset=gb2312");
$key="asdf@#%#%#%";
$sign=md5("chengmo"."中".$key);
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
</head>
<body>
<form action="test2.php">
合作:<input name="coid" value="chengmo" readonly/>
用户名:<input name="username" value="中" readonly/>
sign:<input name="sign" value="<? echo $sign?>"/>
<input type="submit"/>
</form>
</body>
</html>
  甲方代码:(test2.php保存时候选择:utf-8)

<?php
header("Content-type:text/html;charset=utf-8");
$key="asdf@#%#%#%";
$coid=isset($_REQUEST['coid'])?trim($_REQUEST['coid']):"";
$username=isset($_REQUEST['username'])?trim($_REQUEST['username']):"";
$sign=isset($_REQUEST['sign'])?trim($_REQUEST['sign']):"";
echo "_sign=",md5($coid.$username.$key),"</br>";
echo "coid=",$coid,"</br>";
echo "username=",iconv("gb2312","utf-8",$username),"</br>";
echo "sign=",$sign,"</br>";
?>

截图显示:
DSC0001.png

这里只是以一个简单程序做例子,说明跨字符集程序中,签名需要怎么样处理。我们总结一下:
无论什么样字符集,获得对方原始值后,直接先做签名验证,再做转码。这个规律所有语言都适用!!!


疑问:看了web 程序乱码深入分析【基础原理篇】--php为例 可能大家知道的,无论什么应用程序,是不能准确通过字节流判断出它的编码的。 那么我们做接口开发时候,可以仿照下:http协议,在接口里面加入,字符集属性字段。清楚告诉它,我返回将时什么字符。现在,各大支付网关,都有类似扩展字段,让调用接口方,告诉它传入字符编码是那种类型。 你们可以查阅下它们接口看看。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106294-1-1.html 上篇帖子: php 将数据下载为csv文件 下篇帖子: php随机产生六位数密码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表