PHP接口开发签名验证原理详解
接口开发是各系统之间对接的重要方式,其数据是通过开放的互联网传输,对数据的安全性要有一定要求。为了提高传输过程参数的防篡改性,签名sign的方式是目前比较常用的方式。
我这里介绍一种方式,是目前国内互联网公司常用的一种方式,其中淘宝的支付宝支付接口、淘宝开放平台接口、腾讯开放平台等应用的一种方式。
一、签名参数sign生成的方法
第1步: 将所有参数(注意是所有参数),除去sign本身,以及值是空的参数,按参数名字母升序排序。
第2步: 然后把排序后的参数按参数1值1参数2值2…参数n值n(这里的参数和值必须是传输参数的原始值,不能是经过处理的,如不能将"转成”后再拼接)的方式拼接成一个字符串。
第3步: 把分配给接入方的验证密钥key拼接在第2步得到的字符串前面。
第2步: 在上一步得到的字符串前面加上验证密钥key(这里的密钥key是接口提供方分配给接口接入方的),然后计算md5值,得到32位字符串,然后转成大写.
第4步: 计算第3步字符串的md5值(32位),然后转成大写,得到的字符串作为sign的值。
举例:
假设传输的数据是/interface.php?sign=sign_value&p2=v2& p1=v1&method=cancel&p3=&pn=vn(实际情况最好是通过post方式发送),
其中sign参数对应的sign_value就是签名的值。
第一步,拼接字符串,首先去除sign参数本身,然后去除值是空的参数p3,剩下p2=v2&p1=v1&method=cancel& amp;pn=vn,然后按参数名字符升序排序,method=cancel&p1=v1&p2=v2&pn=vn.
第二步,然后做参数名和值的拼接,最后得到methodcancelp1v1p2v2pnvn
第三步,在上面拼接得到的字符串前加上验证密钥key,我们假设是abc,得到新的字符串abcmethodcancelp1v1p2v2pnvn
第四步,然后将这个字符串进行md5计算,假设得到的是abcdef,然后转为大写,得到ABCDEF这个值即为sign签名值。
注意,计算md5之前请确保接口与接入方的字符串编码一致,如统一使用utf-8编码或者GBK编码,如果编码方式不一致则计算出来的签名会校验失败。
二、签名验证方法:
根据前面描述的签名参数sign生成的方法规则,计算得到参数的签名值,和参数中通知过来的sign对应的参数值进行对比,如果是一致的,那么就校验通过,如果不一致,说明参数被修改过。
例子
代码如下 | 复制代码 |
<?php //header('Content-Type: text/xml; charset=utf-8'); include_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'phpsec'.DIRECTORY_SEPARATOR.'Math'.DIRECTORY_SEPARATOR.'BigInteger.php'); include_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'phpsec'.DIRECTORY_SEPARATOR.'Crypt'.DIRECTORY_SEPARATOR.'AES.php'); include_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'phpsec'.DIRECTORY_SEPARATOR.'Crypt'.DIRECTORY_SEPARATOR.'RSA.php'); //密文 $crypttext = 'v66YKULHFld2JElhm/J9qik2Edr1JHdZIc/k/OesU2GbTX2usXyvF4jGvzvoihrrE8FsfKmllmjsMIjO5fdrS/FD20bYFii4JW3BO3bzshXmz6AEs2DWwG4sK9mNojfOC0IsMoV311X5/JlgUoQXkDy4F5HHpYE9d/xGb0g2XE/hnGSSy2cpQcvQtBlBmixwSckNhsEG92lovlOz8ULwkqG5o7x+qB7P/EMII/WaFAXBJXDXvZX7lmGcOgon6wLhKJLGXorP6BIxOg6LGc6Ux7BAt3i9+0lujNgxIq/sDsl23hsr3yOUpV5C5a813nrHx4HJyd/hBT1UvIUml+eTmJwWCpSfs2cvxIUr0CE57JAZVyXjK13shK3IsZHLPPsm/JcDCrdy0Co/d5uIGJAdzXdsQ56xsju+tlvnA1J6yq2tDIfYK/x6k911A5WXLKYxztD1nq+bTYN3Gv/WFfrzVtgWQBrh06ihS2cwvna0S9EV/YPmhnAjJmrX4trNr9NXQ9xaZaW4lGRg87U5QDV+nQjj1THk0XHFc69N9g2+DsAGyEs9tK6U0ZQ72hJZqZhBCDH1UKw0PLyIhJdxpgPPOWGp8/QVVU2julTeKunvgAAEc3n+GoZfqjsCDi1S6T2MTnjWYWNoFRBhvEZFD/revgpasTOzDQa5NqR1B+mUF70r6uw6MWLJ7cT9Tz3jq+CA'; $aeskey = base64_decode('qZe60QZFxuirub2ey4+7+Q=='); //AES解密,采用ECB模式 $aes = new Crypt_AES(CRYPT_MODE_ECB); //设置AES密钥 $aes->setKey($aeskey); //解密AES密文 $plaintext = $aes->decrypt(base64_decode($crypttext)); echo $plaintext; echo '<hr />'; //AES加密明文 //echo $aes->encrypt($plaintext); //rsa公钥 $publickey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCffOeIVYut9jW5w1L5uKX4aDvd837a8JhaWm5S8YqNQfgEmfD9T+rDknXLqMT+DXeQAqGo4hBmcbej1aoMzn6hIJHk3/TfTAToNN8fgwDotHewsTCBbVkQWtDTby3GouWToVsRi1i/A0Vfb0+xM8MnF46DdhhrnZrycERBSbyrcwIDAQAB'; //echo base64_decode($publickey); //rsa签名 $signature = 'XHin4uUFqrKDEhKBD/hQisXLFFSxM6EZCvCPqnWCQJq3uEp3ayxmFuUgVE0Xoh4AIWjIIsOWdnaToL1bXvAFKwjCtXnkaRwUpvWrk+Q0eqwsoAdywsVQDEceG5stas1CkPtrznAIW2eBGXCWspOj+aumEAcPyYDxLhDN646Krzw='; //echo base64_decode($signature); $rsa = new Crypt_RSA(); //设置RSA签名模式 CRYPT_RSA_SIGNATURE_PSS or CRYPT_RSA_SIGNATURE_PKCS1 $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); //var_dump($rsa->createKey()); //生成RSA公钥、私钥 //extract($rsa->createKey()); //使用RSA私钥生成签名 //$rsa->loadKey($privatekey); //$signature = $rsa->sign($plaintext); //使用RSA公钥验证签名 echo $plaintext; $rsa->loadKey(base64_decode($publickey)); echo $rsa->verify($plaintext, base64_decode($signature)) ? 'verified' : 'unverified'; echo '<hr />'; //生成RSA公钥、私钥 //var_dump($rsa->createKey()); extract($rsa->createKey()); //使用RSA私钥加密数据 $rsa->loadKey($privatekey); $ciphertext = $rsa->encrypt($plaintext); //使用RSA公钥解密数据 $rsa->loadKey($publickey); echo $rsa->decrypt($ciphertext); |
修复了一个获取控制器名称方法的bug
控制器的名称都是使用act结尾,使用过程中要删除act。
1。原来的方法
//使用替换act的方法获取控制器名称,很显然当控制器的名称出现act三个字符的时候都会被替换掉产生bug $actName = str_replace( 'act', '', 'ad_client_contactact');
控制器名称 ad_client_cont
2。修复后的方法
//从结尾删除三个字符串
$actName = substr('ad_client_contactact',0,-3);
控制器名称ad_client_contact
1、从第4个字符开始截取到字符串末尾,类似asp中的left:
<?php $str = "www。icoa。cn"; echo substr($str,4); ?> 输出: icoa。cn
2、PHP substr函数从右边截取3个字符,类似asp中的right:
<?php $str = "www。icoa。cn"; echo substr($str,-3); ?> 输出:。cn
3、PHP substr函数从第4个字符开始截取3个字符:
<?php $str = "www。icoa。cn"; echo substr($str,4,3); ?> 输出:ico
4、有时我们知道一个字符串的开始和结尾,中间是不定长的字符,这时除了用PHP substr函数的正则外我们还可以用substr实现(当然要得到中间的字符方法有N种,在此只是举例substr的应用):
本例去掉开头4个字符和结尾3个字符,输出中间的字符串:
<?php $str = "www。icoa。cn"; echo substr($str,4,-3); ?> 输出:icoa
5、对中文看看
$a="直的、竖的、横的、方的、" $a=substr($a,0,-1); 输出结果为:直的、竖的、横的、方的
6、查找指定字符串并删除
$a = "abcababa"; $count=strpos($a,"ab"); $str=substr_replace($a,"",$count,2); 输出结果:cababa
代码虽短,但也算是一个小算法!
7、删除字符串中任何字符的函数
function delStr($start, $end, $orgenStr) { //读取要删除字符位置的前一部分字符串,并赋值给$temp //strpos读取字符第一次出现的位置 //substr读取指定开始与结束位置的子字符串 //echo $before."—". $last; $temp=$orgenStr; while(strpos($temp, $start) && strpos($temp, $end)){ $temp=substr($temp, 0, strpos($temp, $start)).substr($temp,strpos($temp, $end)+strlen($end));; //读取要删除字符位置的后一部分字符串,然后将前后部分连接,并赋值给$temp //返回最后是字符串 } return $temp; } //应用实例 $a="aaaa12345678bbbbtttttttttttttttttttttaaaa12345678bbbb kkkkkkkkkkkkaaaa12345678bbbbttttttttttttttttttttt"; $b="1234"; $c="5678"; echo delStr($b,$c,$a);本文章为各位介绍一篇关于解决PHP报错ZipArchive library is not enabled异常的方法,希望文章能够对大家有帮助。
今天在Linux底下上传Excel文件时,抛出“ZipArchive library is not enabled” 的异常。而我在本地的windows下的代码则是运行正常的。
原因是:在Linux下没有php_zip.dll这个文件(有也不会起作用的),所以需要重新编译一下php的zip模块。
在Unix/Linux下的解决办法 :
1、依次运行如下命令:
cd /usr/src wget http://pecl.php.net/get/zip (默认会在线下载最新版本的) tar zxvf zip.x.x.tgz (所下载的包名) cd zip-1.x.x /usr/bin/phpize (对应的phpize路径 find / -name phpize 出来结果/usr/bin/phpize) ./configure --with-php-config=/usr/bin/php-config (对应的php-config路径) make make instal
2、查看生成的模块路径(安装完之后,屏幕上会提示zip.so的位置):
cd /usr/lib/php/modules/ (对应的extensions路径 /usr/lib/php/modules/)
3、修改php.ini
增加 extension=zip.so
然后同样在php.ini文件中,将zlib.output_compression = Off 改为 zlib.output_compression = On ;
4、最后再重启一下Apache:./apachectl restart ;
这个针对php的zip模块就安装完成了,能够在php中使用ZipArchive类了。
附:在Windows下的解决办法就比较简单了 :
1、在php.ini文件中,将extension=php_zip.dll前面的分号“;”去除
然后同样在php.ini文件中,将 zlib.output_compression = Off 改为 zlib.output_compression = On ;
2、重启Apache服务器。
这篇文章主要介绍了php提取字符串中网站url地址的方法,可通过正则匹配查找并提取出URL地址,需要的朋友可以参考下
$postInfo['answer2'] ='学习php的方法很多,通过搜索引擎可以搜索到很多资料,当然也可以进入PHP二次开发博客学习哦:http://www.111cn.net,一起交流学';
preg_match_all("/http:[\/]{2}[a-z]+[.]{1}[a-z\d\-]+[.]{1}[a-z\d]*[\/]*[A-Za-z\d]*[\/]*[A-Za-z\d]*/",$postInfo['answer2'],$array2); print_r($array2); if(!emptyempty($array2[0])) { foreach ($array2[0] as $k=>$v){ $postInfo['answer2'] = str_replace($array2[0][$k],'',$postInfo['answer2'] ); } }
输出结果:
( [0] => Array ( [0] => http://www.111cn.net ) )简易信息聚合(也叫聚合内容)是一种RSS基于XML标准,在互联网上被广泛采用的内容包装和投递协议。RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,使用非常的多,下面我们来介绍在生成rss时pubDate所需日期时间格式的方法
SS / ATOM 的格式要产生都很简单, 麻烦的是日期格式的产生(RSS => pubDate, ATOM => created).
发现 PHP Date 有提供这些需要的相关全域变量可以使用:(PHP 5.1.1 以后开始支援这些全域变量)
echo DATE_RSS; // D, d M Y H:i:s O echo DATE_ATOM; // Y-m-d\TH:i:sP echo date(DATE_RSS); // Wed, 23 Apr 2008 19:27:19 +0800 echo date(DATE_ATOM); // 2008-04-23T19:27:38+08:00
如果是 MySQL timestamp/datetime format 直接拉出来的资料, 就可以直接使用:
date(DATE_RSS, ($MYSQL_DATETIME_DATA));
目前支持的日期全域变量有以下:
DATE_ATOM: Atom Atom (example: 2005-08-15T15:52:01+00:00) DATE_COOKIE: HTTP Cookies (example: Monday, 15-Aug-05 15:52:01 UTC) DATE_ISO8601: ISO-8601 (example: 2005-08-15T15:52:01+0000) DATE_RFC822: RFC 822 (example: Mon, 15 Aug 05 15:52:01 +0000) DATE_RFC850: RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC) DATE_RFC1036: RFC 1036 (example: Mon, 15 Aug 05 15:52:01 +0000) DATE_RFC1123: RFC 1123 (example: Mon, 15 Aug 2005 15:52:01 +0000) DATE_RFC2822: RFC 2822 (Mon, 15 Aug 2005 15:52:01 +0000) DATE_RFC3339: Same as DATE_ATOM DATE_RSS: RSS (Mon, 15 Aug 2005 15:52:01 +0000) DATE_W3C: World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00)
PHP 预定义的日期格式
自 PHP 5.1.1 起定义有以下常量来提供标准日期表达方法,可以用于日期格式函数
echo DATE_RSS; // D, d M Y H:i:s O echo DATE_ATOM; // Y-m-d\TH:i:sP echo date(DATE_RSS); // Wed, 23 Apr 2008 19:27:19 +0800 echo date(DATE_ATOM); // 2008-04-23T19:27:38+08:00
虽然格式简单, 但用PHP内的预定义格式岂不更加方便.
目前PHP所有支持的日期格式:
DATE_ATOM: Atom Atom (example: 2005-08-15T15:52:01+00:00) DATE_COOKIE: HTTP Cookies (example: Monday, 15-Aug-05 15:52:01 UTC) DATE_ISO8601: ISO-8601 (example: 2005-08-15T15:52:01+0000) DATE_RFC822: RFC 822 (example: Mon, 15 Aug 05 15:52:01 +0000) DATE_RFC850: RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC) DATE_RFC1036: RFC 1036 (example: Mon, 15 Aug 05 15:52:01 +0000) DATE_RFC1123: RFC 1123 (example: Mon, 15 Aug 2005 15:52:01 +0000) DATE_RFC2822: RFC 2822 (Mon, 15 Aug 2005 15:52:01 +0000) DATE_RFC3339: Same as DATE_ATOM DATE_RSS: RSS (Mon, 15 Aug 2005 15:52:01 +0000) DATE_W3C: World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00)
生成rss例子
header("Content-type: application/xml"); //定义header头,以防止chrome内核的浏览器不支持rss订阅,如果不支持就输出xml格式的文件 /** * 查询数据库,获取要输出rss的数据 */ $database = "nameofthedatabase"; $dbconnect = mysql_pconnect(localhost, dbuser, dbpassword); mysql_select_db($database, $dbconnect); $query = "select link, headline, description from `headlines` limit 15"; $result = mysql_query($query, $dbconnect); while ($line = mysql_fetch_assoc($result)) { $return[] = $line; } $now = date("D, d M Y H:i:s T"); $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?> <rss version=\"2.0\"> <channel> <title>山东道路交通安全网-$lanmu</title> <link>http://sdjtaq.cn/rss</link> <description>Latest 100 articles of $lanmu</description> <pubDate>$now</pubDate> <lastBuildDate>$now</lastBuildDate> <docs>http://someurl.com</docs> <managingEditor>810706080@qq.com</managingEditor> <webMaster>810706080@qq.com</webMaster> "; foreach ($artList as $line) { $date = strtotime($line['add_time']); //将数据库的时间格式化成时间戳 $output .= "<item> \n" . "<title>" . $line['title'] . "</title>\n" . " <link>http://sdjtaq.cn/aq_show_" . $line['id'] . ".html</link>\n" . "<description><![CDATA[" . $line['zhaiyao'] . "]]></description>\n" . "<pubDate>" . date("D, d M Y H:i:s O", $date) . "</pubDate>\n" . "</item>\n"; } $output .= "</channel>\n</rss>"; echo $output;
相关文章
- 这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
- 这篇文章主要给大家分享的是TypeScript 索引签名的理解,索引签名由方括号中的索引名称及其类型组成,后面是冒号和值类型:{ [indexName: KeyType]: ValueType }, KeyType 可以是一个 string、number 或 symbol,而ValueType 可以是任何类型,下面就俩简单了解一下吧...2021-10-15
- 这篇文章主要介绍了vue接口请求加密实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-12
Django def clean()函数对表单中的数据进行验证操作
这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09- 这篇文章主要为大家详细介绍了JavaScript实现密码框输入验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-01
- 这篇文章主要介绍了Nest.js 授权验证的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-22
- 这篇文章主要介绍了el-table树形表格表单验证(列表生成序号),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-01
- 这篇文章主要介绍了C#简单了解接口(Interface)使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-08
- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
- 这篇文章主要介绍了C# Rx的主要接口深入理解的相关资料,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了selenium 反爬虫之跳过淘宝滑块验证功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-27
- 这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
vue element table中自定义一些input的验证操作
这篇文章主要介绍了vue element table中自定义一些input的验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18- 这篇文章主要为大家详细介绍了js canvas实现滑块验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-14
- 这篇文章主要介绍了vue设置全局访问接口API地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-14
- 在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12
- 这篇文章主要为大家详细介绍了vue实现表单验证小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-29
- 本文章来为各位介绍一篇利用PS制作“签名”GIF小动画的例子,希望这个制作过程能够帮助到各位朋友,各位进入看看吧。 先给大家看下效果,有兴趣的童鞋→_→可以...2016-09-14
- php怎么写api接口?本文介绍了php写api接口的实例代码,有兴趣的同学可以参考一下。 http://localhost/openUser.php?act=get_user_list&type=json在这里openUser.php...2017-07-06
- 这篇文章主要介绍了vue配置多代理服务接口地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-08