在传统的C/S软件开发中, 通常都是客户端将用户名、密码以一定的形式加密后发往服务端验证.服务端根据客户端传送上来的用户名、密码到数据库上查询是否有相应的记录来判断该用户是否合法.
这样做的缺点很明显,一旦网络中有类似于sniffer一类的监测器该用户信息就很容易被伪造. 根本原因在于直接传输用户名/密码, 跟加不加密没有太多关系.举个例子来说,如果用户名是Jackson,密码不知道. 监测后得知加密后的用户名是#I$UU#U(Q!@#$@,加密后的密码是@$)*^&^&%@!@&&#$@#@#$#&$. 那么仅需发送那两个字符串就可以伪造Jackson.
那样无疑是很不安全的. 下面给出一个基于消息摘要的身份验证及其实现.
先看图
由上图可知密码不再网络上传输, 取而代之的是服务器发送给客户端的Nonce及包含用户名/密码/nonce在内的加密串. Nonce只能用一次,并且会超时. 这样可以有效地对抗抓包/重放包等尝试性的猜测攻击.
事实上这是RFC2609摘要认证的一个实现例子.
RFC2609大致定义了一个传统的由服务器生成随机数来维护安全性的摘要认证架构。认证响应由下列组成(HA1、HA2、A1、及A2为字符串变量的名称):
- HA1 = MD5(A1) = MD5(username:realm:password)
- HA2 = MD5(A2) = MD5(method:digestURI)
- response = MD5(HA1:nonce:HA2)
-
- 因为MD5是不可逆的,所以想从加密串中推导出用户名/密码也是不可能的. 并且在这个公式中,其实并没有直接用到用户名/密码.因此允许数据库存放md5之后的数值HA1.这样可以有效防止数据库被攻破后照成的密码泄露问题.
-
- 实现代码见http://download.csdn.net/detail/jackson_xp/5625287
事实上这是RFC2609
摘要认证的一个实现例子.