代码搬运工 2017-11-23 15:38:12 2907次浏览 0条回复 0 0 0

新人第一次发帖,望各位大佬海涵 O(∩_∩)O

遇到的一个功能,项目A需要请求项目B的接口,A和B是不同的服务器,A通过CURL以GET方式请求B的接口,URL是正常的类似这种:

http://www.yiichina.com/search?q=url参数编码&page=2

每个参数的键值很明了,然而在B的接口里面将接收到的某个参数存入了数据库,这种情况下,如果这个接口被别人知道了,很容易修改到B的数据库,所以就需要对参数进行编码和加密签名

1.URL参数编码

原文:分享如何使用PHP将URL地址参数进行加密传输提高网站安全性

代码可以直接复制,修改namespace即可:

<?php
namespace common\helper;

class UrlEncryption {

    public static $key_url_md_5 = 'test_md5_key'; //可以更换为其它的加密标记,可以自由发挥

    private static function keyED($txt){       
        $encrypt_key =    md5(self::$key_url_md_5);
        $ctr=0;       
        $tmp = "";       
        for($i=0;$i<strlen($txt);$i++)       
        {           
            if ($ctr==strlen($encrypt_key))
            $ctr=0;           
            $tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);
            $ctr++;       
        }       
        return $tmp;   
    }    

    private static function encrypt($txt)   {
        $encrypt_key = md5(mt_rand(0,100));
        $ctr=0;       
        $tmp = "";      
         for ($i=0;$i<strlen($txt);$i++)       
         {
            if ($ctr==strlen($encrypt_key))
                $ctr=0;           
            $tmp.=substr($encrypt_key,$ctr,1) . (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));
            $ctr++;       
         }       
         return self::keyED($tmp);
    } 
        
    private static function decrypt($txt){       
        $txt = self::keyED($txt);       
        $tmp = "";       
        for($i=0;$i<strlen($txt);$i++)       
        {           
            $md5 = substr($txt,$i,1);
            $i++;           
            $tmp.= (substr($txt,$i,1) ^ $md5);       
        }       
        return $tmp;
    }

    private static function encrypt_url($url){
        return rawurlencode(base64_encode(self::encrypt($url)));
    }

    private static function decrypt_url($url){
        return self::decrypt(base64_decode(rawurldecode($url)));
    }

    public static function setUrl($str){
        return self::encrypt_url($str);
    }

    public static function getUrl($str){
        $str = self::decrypt_url($str);
        $url_array = explode('&',$str);
        if (is_array($url_array))
        {
            foreach ($url_array as $var)
            {
                $var_array = explode("=",$var);
                $vars[$var_array[0]]=$var_array[1];
            }
        }
        return $vars;
    }

}
使用方法:

例如URL地址为B项目TestController下的actionTest:http://www.demo.com/test/test?a=1&b=2&c=3

  1. 使用parse_url()将完整的URL字符串解析成数组,其中键名为'query'的数组单元的值就是URL中的参数字符串a=1&b=2&c=3
  2. 直接调用UrlEncryption类的setUrl()方法,将得到的参数字符串传入,就能得到编码字符串(记得use这个类)

到这里就将URL中的参数进行了编码,B项目中只接收这个编码字符串,然后同样方法调用UrlEncryption类的getUrl()方法将字符串传入就能直接得到参数数组array('a' => 1, 'b' => 2, 'c' => 3),这样就避免了参数键值的明文显示

但是如果直接修改这个编码字符串,在B中解码后得到的数据可能会跟原本传递的数据不同,在这里我又进行了一次签名

生成MD5签名

文章:php生成md5签名原理

可以到上面的文章中直接复制代码封装成一个类,这里就不贴代码了,使用方法也很简单。

在这里,我将A中需要传递的参数签名后,同编码字符串一起传递给B,如:http://www.demo.com/test/test?code=编码字符串&sign=数据签名 ,在B中将编码字符串解码后的数组进行同样方法的签名,对比签名是否一致来验证参数是否正确

结论:通过原参数进行编码后解决了参数的明文显示,同时通过参数的签名保证数据传递的一致,基本解决了我的问题

最后再次附上参考使用到的文章链接: 分享如何使用PHP将URL地址参数进行加密传输提高网站安全性 php生成md5签名原理

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册