文档章节

URL地址参数进行加密传输提高网站安全性

高处胜寒
 高处胜寒
发布于 2017/11/09 19:16
字数 2197
阅读 2693
收藏 0

通过密钥对url上的参数进行签名,比如url上有三个参数,按一定顺序排列后用一个只有服务端知道的密钥签名放在<a href="http://www.xxx.com/?a=1&b=2&c=3&sig=xxxxxxxx">里,这样,如果用户改了里面参数的内容,比如把a=1改成了a=2,但不知道你的密钥,也无法模拟你的签名,后台通过接收到的参数列表,用密钥进行签名校验,就可以知道这个url是不是原始你写出去的url了。

 

将要提交的参数先做加密,然后把加密的信息做一次md5摘要,也就是签名,然后把摘要连同参数一起回传给服务器,服务器拿到参数后,同样的方式加密做md5摘要,然后两个摘要做对比,如果不相等参数便是被篡改了,否则可信。这种方式已经是很成熟的url参数防篡改技术了,简单易用成本低,安全系数高,并且不会大大增加url的长度,业内很多公司都在使用这种方式,比如阿里巴巴,腾讯的接口等。

 

|----------------------------------------

加密的GET参数

WEB驱动事件与交互的最基本的方法就是通过GET参数,我想你懂paperen说的是什么意思的。

www.example.com/news/?id=234

www.example.com/goods.php?id=2

http://www.google.com.hk/search?hl=zh-CN&newwindow=1&safe=strict&q=GET%E5%8F%82%E6%95%B0&aq=f&aqi=&aql=&oq=

简单来说就是那个问号后面的都可以称之为GET参数,因为这种形式会让浏览器向服务器请求时将问号后面的字符都加到请求数据中,只是那不是我们要了解的事情而已,而很直接的表现就是在地址栏看到这些很长的参数。

不知道大家有没有去修改这些参数的冲动,因为修改它们实在是太容易了,而且是暴露在地址栏的,我们都可以随便修改,或者将id=2改为id=test,但正如有写过web代码的人都应该知道一件事情就是“很可能这个参数会被用来做一些事情“,最常见的就是作为一个字符或者数字拼接到一条sql里面,然后查出相应的数据,或者根据该参数让程序反应不同的结果……

而重要的是,paperen我认为大部分这种暴露get参数带来的负面影响是,一些好奇心或者恶意的浏览者会通过这些参数对您的网站进行一些检测与攻击,显然这并不是网站运营与开发者想听到的消息。

20110223173446

web服务器来说并不知道哪些请求是恶意的是非法的,因为服务器对每个请求都是平等的,但当然不是说100个浏览者中会有99个是带恶意的,相反,恶意性的浏览者可能只有1个,但就是这么只有1个才让我们感到害怕,因为我们不知道这个带恶意的浏览者会从我们的服务器获得什么信息,发现什么漏洞……所以这也说明了为什么我们要将我们的代码写得更加稳定更加强壮,特别是应对一些异常数据的时候,这也正是为什么在发布最后要经过一个测试的原因……好吧,下面就直接奔向主题算了。

paperen认为在一定程度上你可以去屏蔽get参数的表现方式来让那些对get参数敏感的人对你失去兴趣,you know,这并不是一个很高深的方案,别怕……

如果将

www.example.com/news/?id=3&uid=45&name=paperen

变为

www.example.com/news/?get=0qMZJevzDZaP9Wc77sh4uvhSrUXW0lYj13I4oxwNM6%

你觉得这个url给你感觉是什么……(paperen我会想OMG,这堆字符串真TMD BT了……很恶心),我们没法从这么一堆BT的字符串中想象它原来的格式是id=3&uid=45&name=paperen,没错这是个丑陋的URL,对seo有了解的人或者不推荐这么做,paperen认为在安全与seo之间你需要有个折中点,采取符合您的期望与要求的方案就可以了(不是讨论重点)。

paperen想这会在安全性上更加给力,因为大部分的浏览者(或者应该说是地球人)都很难去理解这串看上去毫无意义的参数。so下面提供一下实现的方法(其实真的很简单)。想象一下自己平时是怎样处理这些get参数的。

 
  1. <?php
  2. $id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : '';
  3. if ( $id ) {
  4. //do something
  5. }
  6. ?>
  7. <a href="example.php?id=164332">Link</a>

然后我们需要一个加密算法(它也应该是可以解密的),很明显已经直接排除了md5与crypt,因为都是单向性的。故可以使用base64来实现这个,php对应的两个加解密函数分别是base64_encode与base64_decode。

最后一点是我们不是单纯对id使用这个加密,不单单是要让url变成这样。www.example.com/news/?id=Mw==&uid=NDU=&name=cGFwZXJlbg==,这样只是对参数数据进行了加密,但是有哪些参数还是暴露在外面。我们的目标是”只有一个参数“。或者可以这样写。

 
  1.  
  2. <?php
  3.  
  4. //是否开启URL加密模式
  5. define('OPEN_URL_ENCODE', true);
  6. //加密类型
  7. define('GET_ENCODE_TYPE', 'base64');
  8. //自定义GET接受标记
  9. define('GET_TAG', 'get');
  10.  
  11. //需要传递的GET参数
  12. $args = array(
  13. 'id' => 1533,
  14. 'type' => 2,
  15. );
  16.  
  17. //如果开启URL加密模式需要进行一些特殊处理
  18. if ( OPEN_URL_ENCODE ) {
  19. $_GET = extract_arg( $_GET );
  20. }
  21.  
  22. //整理参数
  23. function format_arg( $url, $args ) {
  24. return (OPEN_URL_ENCODE) ? $url . '?' . GET_TAG . '=' . make_my_urlarg( arg_arr2str( $args ) ) : $url . '?' . $tmp;
  25. }
  26.  
  27. //还原参数
  28. function extract_arg( $arr ) {
  29. if ( isset( $arr[GET_TAG] ) ) {
  30. return arg_arr2str( make_my_urlarg( $arr[GET_TAG] , true ), true );
  31. } else {
  32. return array('');
  33. }
  34. }
  35.  
  36. //数组字符串互换
  37. function arg_arr2str( $data, $is_str2arr = false ) {
  38. $tmp = '';
  39. if ( $is_str2arr && is_string( $data ) ) {
  40. $arr = explode('&', $data);
  41. foreach( $arr as $index => $data ) {
  42. if ( false !== strpos($data, '=') ) {
  43. list($k , $val) = explode('=', $data);
  44. $tmp[$k] = $val;
  45. }
  46. }
  47. } else if( !$is_str2arr && is_array( $data ) ) {
  48. foreach( $data as $k => $val ) $tmp .= '&' . $k . '=' . $val;
  49. $tmp = substr($tmp, 1);
  50. }
  51. return $tmp;
  52. }
  53.  
  54. //根据相应的算法加解密参数
  55. function make_my_urlarg($str, $is_decode = false) {
  56. if ( 'base64' == GET_ENCODE_TYPE ) {
  57. return ($is_decode) ? base64_decode($str) : base64_encode($str);
  58. }
  59. }
  60.  
  61. //还是一如既往地接收GET参数,感觉这个加解密处理与我们无关
  62. $id = isset( $_GET['id'] ) ? intval($_GET['id']) : '';
  63. $type = isset( $_GET['type'] ) ? intval($_GET['type']) : '';
  64. if ( $id ) {
  65. //do something
  66. }
  67.  
  68. $url = format_arg('example.php', $args);
  69. echo "<p>$url</p>";
  70.  
  71. print_r( $_GET );
  72. echo '<p></p>';
  73.  
  74. ?>
  75. <a href="<?php echo $url; ?>">Link</a>

你能调用的函数其实就是format_arg与extract_arg,就这样简单已经给全局变量$_GET加上一层马甲。运行效果如下。

20110223190139

对,我们还是可以一如既往地使用$_GET['id']来获取这个参数,但是原来的URL却变得有点不可看透了,当然从这个你可以延伸到其他超级变量上,比如POST(用在POST上不太好,原因是加甲是由服务端执行的,而大部分POST数据是变动的不像URL传参数这样是我们预定好的),SESSION,COOKIE。或许用在COOKIE上也是一个不错的选择。

如果用JS控制页面跳转到某个带参数的URL时可能要有点折腾,只要你头脑有个概念:加甲是要靠服务端程序的,应该就好办了。

如果感觉使用base64加密还是会被识穿那么你可以使用以下这个函数作为加解密核心。

 
  1.  
  2. /**
  3. * authcode 摘自UChome
  4. * @param string $string 明文
  5. * @param string $operation ENCODE加密/DECODE解密
  6. * @param string $key 密钥(可以在配置文件中定义)
  7. * @param string $expiry 有效期?
  8. * @return string
  9. */
  10. function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
  11.  
  12. $ckey_length = 1;
  13. $key = md5($key ? $key : '');
  14. $keya = md5(substr($key, 0, 16));
  15. $keyb = md5(substr($key, 16, 16));
  16. $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
  17.  
  18. $cryptkey = $keya . md5($keya.$keyc);
  19. $key_length = strlen($cryptkey);
  20.  
  21. $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
  22. $string_length = strlen($string);
  23.  
  24. $result = '';
  25. $box = range(0, 255);
  26.  
  27. $rndkey = array();
  28. for($i = 0; $i <= 255; $i++) {
  29. $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  30. }
  31.  
  32. for($j = $i = 0; $i < 256; $i++) {
  33. $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  34. $tmp = $box[$i];
  35. $box[$i] = $box[$j];
  36. $box[$j] = $tmp;
  37. }
  38.  
  39. for($a = $j = $i = 0; $i < $string_length; $i++) {
  40. $a = ($a + 1) % 256;
  41. $j = ($j + $box[$a]) % 256;
  42. $tmp = $box[$a];
  43. $box[$a] = $box[$j];
  44. $box[$j] = $tmp;
  45. $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  46. }
  47.  
  48. if($operation == 'DECODE') {
  49. if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  50. return substr($result, 26);
  51. } else {
  52. return '';
  53. }
  54. } else {
  55. return $keyc.str_replace('=', '', base64_encode($result));
  56. }
  57. }

还支持密钥,也就是说密钥不对也不能解密,很给力吧~~

下面是一个完整的DEMO,希望对你有帮助。

I AM HERE!这里

 

参考资料:

http://paperen.com/post/get-encode【推荐】

http://blog.csdn.net/hashsound_wang/article/details/8113766【推荐】

http://blog.csdn.net/sdutphp/article/details/51991738

http://www.mdaima.com/jingyan/36.html

http://blog.csdn.net/youngqj/article/details/6200100

 

 

 

 

 

© 著作权归作者所有

高处胜寒

高处胜寒

粉丝 9
博文 213
码字总数 148499
作品 0
西安
程序员
私信 提问
分享如何使用PHP将URL地址参数进行加密传输提高网站安全性

大家在使用PHP进行GET或POST提交数据时,经常会在URL带着参数进行传递,比如www.mdaima.com/get.php?id=1&page=5,这里就将id编号和page页码进行了参数传递,如果这样直接明文传输,会将参数...

james_laughing
2016/10/28
36
0
python web开发 了解基础点

python web开发 [if !supportLists]1-1 [endif]预期目标 技能:学习[Django] [Tornado] [Flask]web开发框架 经验:熟悉[门户网站在线电商管理平台、项目开发]开发流程和处理过程 总结:掌握[...

AAA年华
2018/01/10
0
0
Java学习手册:Java网络编程面试问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/MaybeForever/article/details/95471329 1、Java学习手册:Java基础知...

浩比浩比
08/27
0
0
一篇文章读懂阿里云视频点播内容安全机制

1. 概述 如何保障视频内容的安全,不被盗链、非法下载和传播,是困扰众多企业已久的问题,特别是独播剧、在线教育、财经金融、行业培训等在线版权视频领域尤为迫切,处理不好会造成极为严重的...

樰篱
2018/07/02
0
0
有了这 4 大特性,CDN 好用到飞起

随着 CDN 市场的快速发展和网络新技术的不断涌现,目前的 CDN 已不仅仅是当初简单的内容分发,同时也是新特性研发、新技术推广及实践的平台。这些新技术、新特性,或者能够保障 CDN 安全性,...

又拍云
2018/09/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

反编译9.png图片还原

本文链接:https://blog.csdn.net/a1140778530/article/details/10528507 经常反编译apk文件找资源,9.png的文件处理起来很麻烦。 最近使用Ant自动编译打包app时,从别处搜罗来的9.png文件导...

shzwork
22分钟前
6
0
Shell脚本应用 – for、while循环语句

一、for循环语句 在实际工作中,经常会遇到某项任务需要多次执行的情况,而每次执行时仅仅是处理的对象不一样,其他命令相同。例如:根据通讯录中的姓名列表创建系统账号等情况。 当面对各种...

linux-tao
22分钟前
5
0
RPA风潮下企业财务工作模式的变革

RPA(机器人流程自动化)在财务领域的应用,正给企业财务带来前所未有的改变。 前RPA时代,财务领域面临的痛点 在RPA机器人应用之前,企业财务工作进程的推进,主要通过财务人员人工操作或信...

UiBot
27分钟前
5
0
Hive之命令行修改表注释

最近遇到一个需求,在不重建表的情况下,修改表的注释,hive有没有类似关系型数据库的SQL命令来修改呢,找了下,亲测有效,如下List-1 List-1 hive>use your_schemahvie>ALTER TABLE tabl...

克虏伯
28分钟前
5
0
是什么,它的作用是什么

在HTML文档的首部往往会有这么一句话<!DOCTYPE html>,许多时候我们忽视了它的存在,它实际上是一个声明,告诉浏览器用哪种HTML版本的规范来解读HTML文档。 尽管我们不给出这句声明浏览器照样...

前端老手
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部