base.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. /**
  3. *功能:小小贝接口公用函数
  4. *详细:提供了签名、验签、提交等共用函数
  5. *版本:2.0.2
  6. *修改日期:2016-12-15
  7. '说明:
  8. '以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己的需要,按照技术文档编写,并非一定要使用该代码。
  9. '该代码仅供学习和研究小小贝接口使用,只是提供一个参考。
  10. */
  11. /**格式化公钥
  12. * $pubKey PKCS8格式的公钥串
  13. * return pem格式公钥, 可以保存为.pem文件
  14. */
  15. function formatPubKey($pubKey) {
  16. $fKey = "-----BEGIN PUBLIC KEY-----\n";
  17. /* $len = strlen($pubKey);
  18. for($i = 0; $i < $len; ) {
  19. $fKey = $fKey . substr($pubKey, $i, 64) . "\n";
  20. $i += 64;
  21. }*/
  22. $fKey .= str_replace(" ","\n",$pubKey);
  23. $fKey .= "\n-----END PUBLIC KEY-----";
  24. return $fKey;
  25. }
  26. /**格式化公钥
  27. * $priKey PKCS8格式的私钥串
  28. * return pem格式私钥, 可以保存为.pem文件
  29. */
  30. function formatPriKey($priKey) {
  31. $fKey = "-----BEGIN RSA PRIVATE KEY-----\n";
  32. /*$len = strlen($priKey);
  33. for($i = 0; $i < $len; ) {
  34. $fKey = $fKey . substr($priKey, $i, 64) . "\n";
  35. $i += 64;
  36. }*/
  37. $fKey .= str_replace(" ","\n",$priKey);
  38. $fKey .= "\n-----END RSA PRIVATE KEY-----";
  39. return $fKey;
  40. }
  41. /**RSA签名
  42. * $data待签名数据
  43. * $priKey商户私钥
  44. * 签名用商户私钥
  45. * 使用MD5摘要算法
  46. * 最后的签名,需要用base64编码
  47. * return Sign签名
  48. */
  49. function sign($data, $priKey) {
  50. //调用openssl内置签名方法,生成签名$sign
  51. openssl_sign($data, $sign, $priKey, OPENSSL_ALGO_MD5);
  52. //base64编码
  53. $sign = base64_encode($sign);
  54. $sign = urlencode($sign);
  55. return $sign;
  56. }
  57. /**RSA验签
  58. * $data待签名数据
  59. * $sign需要验签的签名
  60. * $pubKey小小贝公钥
  61. * 验签用小小贝公钥,摘要算法为MD5
  62. * return 验签是否通过 bool值
  63. */
  64. function verify($data, $sign, $pubKey) {
  65. //调用openssl内置方法验签,返回bool值
  66. $result = (bool)openssl_verify($data, base64_decode($sign), $pubKey, OPENSSL_ALGO_MD5);
  67. //返回资源是否成功
  68. return $result;
  69. }
  70. /**
  71. * RSA验签
  72. */
  73. function parseRespRsa($content, $pkey) {
  74. $response = json_decode($content);
  75. $sign = $response->sign;
  76. //取出验证签名正文,空格转为加号
  77. $sign = str_replace(' ', '+', $sign);
  78. foreach($response->info as $k=>$v){
  79. if($k!='money'){ //金额保留两位小数
  80. $transdata[$k]=trim($v);
  81. }else{
  82. $transdata[$k]=sprintf("%.2f", $v);
  83. }
  84. }
  85. //转换为校验签名格式
  86. $content = createLinkstringUrlencode($transdata);
  87. //校验签名
  88. $pkey = formatPubKey($pkey);
  89. return verify($content, $sign, $pkey);
  90. }
  91. /**
  92. * MD5验签
  93. */
  94. function parseRespMd5($content, $md5key) {
  95. $response = json_decode($content);
  96. $sign = $response->sign;
  97. foreach($response->info as $k=>$v){
  98. if($k!='money'){ //金额保留两位小数
  99. $transdata[$k]=trim($v);
  100. }else{
  101. $transdata[$k]=sprintf("%.2f", $v);
  102. }
  103. }
  104. //转换为校验签名格式
  105. $content = createLinkstringUrlencode($transdata);
  106. $content .= '&key='.$md5key;
  107. //生成MD5签名
  108. $check = md5($content);
  109. return $sign==$check;
  110. }
  111. /**
  112. * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
  113. * @param $para 需要拼接的数组
  114. * return 拼接完成以后的字符串
  115. */
  116. function createLinkstringUrlencode($para) {
  117. //使用ASCII码正序
  118. ksort($para);
  119. $arg = "";
  120. while (list ($key, $val) = each ($para)) {
  121. $arg.=$key."=".$val."&";
  122. }
  123. //去掉最后一个&字符
  124. $arg = substr($arg,0,count($arg)-2);
  125. //如果存在转义字符,那么去掉转义
  126. if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
  127. return $arg;
  128. }
  129. /**
  130. * curl方式发送post报文
  131. * $remoteServer 请求地址
  132. * $postData post报文内容
  133. * $userAgent用户属性
  134. * return 返回报文
  135. */
  136. function request_by_curl($remoteServer, $postData) {
  137. $ch = curl_init();
  138. curl_setopt($ch, CURLOPT_URL, $remoteServer);
  139. curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
  140. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  141. $data = urldecode(curl_exec($ch));
  142. curl_close($ch);
  143. return $data;
  144. }
  145. /**
  146. * 组装request报文
  147. * $reqJson 需要组装的json报文
  148. * $md5key md5密钥
  149. * return 返回组装后的报文`
  150. */
  151. function composeMd5($reqJson, $md5key) {
  152. //获取待签名字符串
  153. $content = createLinkstringUrlencode($reqJson);
  154. $content .= '&key='.$md5key;
  155. //生成MD5签名
  156. $sign = md5($content);
  157. if($reqJson['psw']){
  158. unset($reqJson['psw']);
  159. }
  160. $content = json_encode($reqJson);
  161. $reqData = "transdata=".urlencode(trim($content))."&sign=".$sign."&signtype=MD5";
  162. return $reqData;
  163. }
  164. /**
  165. * 组装request报文
  166. * $reqJson 需要组装的json报文
  167. * $vkey cp私钥,格式化之前的私钥
  168. * return 返回组装后的报文`
  169. */
  170. function composeRsa($reqJson, $vkey) {
  171. //获取待签名字符串
  172. $content = createLinkstringUrlencode($reqJson);
  173. //格式化key,建议将格式化后的key保存,直接调用
  174. $vkey = formatPriKey($vkey);
  175. //生成RSA签名
  176. $sign = sign($content, $vkey);
  177. $content = json_encode($reqJson);
  178. $reqData = "transdata=".urlencode(trim($content))."&sign=".urlencode($sign)."&signtype=RSA";
  179. return $reqData;
  180. }
  181. /**
  182. * 发送post请求
  183. * $Url 请求地址
  184. * $reqData 请求的内容
  185. * return 返回服务端响应数据
  186. */
  187. function HttpPost($Url,$reqData){
  188. $respData = request_by_curl($Url,$reqData);
  189. return $respData;
  190. }
  191. function get_real_ip(){
  192. $ip=false;
  193. if(!empty($_SERVER['HTTP_CLIENT_IP'])){
  194. $ip=$_SERVER['HTTP_CLIENT_IP'];
  195. }
  196. if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
  197. $ips=explode (', ', $_SERVER['HTTP_X_FORWARDED_FOR']);
  198. if($ip){ array_unshift($ips, $ip); $ip=FALSE; }
  199. for ($i=0; $i < count($ips); $i++){
  200. if(!eregi ('^(10│172.16│192.168).', $ips[$i])){
  201. $ip=$ips[$i];
  202. break;
  203. }
  204. }
  205. }
  206. return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
  207. }
  208. function clean($str){
  209. $qian = array(" "," ","\t","\n","\r","-","BEGIN","PRIVATE","KEY","END","PUBLIC");
  210. return str_replace($qian, '', $str);
  211. }
  212. ?>