关于WSSE验证-- 一种验证用户的方法
大家通常验证用户做法:
1. BASIC验证模式: 把用户名和密码采用Base64编码之后,放在HTTP HEADER里,发到服务器的。
2. FORM验证模式: 就什么都不处理,直接发到服务器。
3. 还有其他证书验证,摘要验证等,这些不在这篇文章讨论范围。
由于是明文传输,密码很容易被截获,从而造成密码的丢失。今天和老大讨论RESTful的模式时,想到了认证的问题,因为REST提倡无状态,我们老大提到了WSSE的问题,于是我就搜索一下。
密码传输的问题通常是用HTTPS来解决,当然这个很完美,但有些限制。有些情况下不能用HTTPS来解决,例如多个应用使用一个单独IP地址来访问时,由于服务器证书里的信息和域名是必须匹配的,所以一个应用使用了HTTPS, 而另一个就不能用了。还有一个办法就是用摘要验证,当然也可以解决这个问题,但是需要在服务器上配置相应的功能模块。如果服务器不可控(例如临时借用别人的服务器)也没有办法做到。
而WSSE的验证模式可以解决以上问题。不需在服务器做额外配置。具体过程如下:
1. 开始于两个信息: 用户名和密码。
2. 创建一个随机的nonce(不知道应该译成什么,反正就是随机的一个只能用一次的字符串),这个产生算法要够强健,不能让人猜出下一个产生的是什么。
3.创建一个"产生时间戳", 并转换成W3DTF格式
4.创建一个密码摘要:
PasswordDigest = Base64 \ (SHA1 (Nonce + CreationTimestamp + Password))
举例说明:
1.用户发一个请求:
2. 由于没有验证信息,服务器以401来响应:
4.服务器通过时间戳和Nonce以及服务器保存的密码进行生成摘要,如果通过验证就可以允许用户访问资源。
这样一个过程,我觉得能解决一些问题,但是还有一些疑问:
1.由于客户要生成摘要和client nonce,客户端必须具有生成它们的能力,或者浏览器支持这种协议。
现在客户端的能力都比较强大,javascript就可以实现摘要的生成。具体程序参考:http://pajhome.org.uk/crypt/md5/,目前为止好像不没有哪个浏览器支持这种协议的。
2.由于只发送摘要,并没有真正发送密码,解决中间攻击的担忧。
这个不错,就要的这种效果。
3.由于nonce是只用一次,下次就随机产生另一个,由于这个是在客户端产生的,如果产生暴力猜测密码的情况怎么办?
这里的nonce只用一次就失效,可以防止黑客的replay攻击。但这过程中没有防止暴力攻击,不过有一个时间戳应该可以利用,如在服务器判断3或者1,2秒之内不能重试登录, 这个虽然不能完全避免,但至少可以减少一些攻击次数。其实最好的解决办法就是强口令,一个强口令就把这个问题解决的比较彻底了。如果不能强制用户使用强口令的话,我们可以加入通常采用的验证码的机制。还有就是上面提到的server nonce应该也可以直到一些作用。
4.如果服务器不保存真正的密码,而是只保存摘要的话,那用这种方法岂不是不能验证用户的合法性了?
如果服务器不保存真正的密码,而是摘要。如LDAP里一般就不保存明文密码,一般数据库里也不会保存真正明文密码,这个问题我还真想不到什么办法。如果服务器的摘要算法和客户端完全一致的话,可以用以下方法生成客户端摘要:
PasswordDigest = Base64 \ (SHA1 (Nonce + CreationTimestamp + DIGEST(Password)))。
就是把Password生成摘要,然后再用组合生成新的摘要。这样在服务器端也能顺利的验证用户的合法性。
我觉得这个方法可以和其他方法结合使用,应该效果不错。至少多了一层防护。
本文的思想主要来自:http://www.xml.com/pub/a/2003/12/17/dive.html, 也引用他的测试的HTTP数据。加上我自己的理解。
如有不妥,希望能够得到指正。最后感谢“Atom Authentication”文章作者Mark。但是这里面的Atom和WSSE有什么关系,并没有搞清楚,可能Atom只是WSSE的一种实现? 望知道的哥们姐妹给一些提示。
1 楼 grandboy 2009-07-29 文章本来是发在博客里的,作为自己思路一种整理方式。但是后来仔细想想,感觉还有些地方需要讨论,今天就发到论坛上来了。希望大家能指出不足,同时也讲一下你们的系统是怎么验证用户的。 2 楼 grandboy 2009-07-30 难道大家对这个话题不感兴趣? 真诚希望与有这方面经验的高人讨论。 3 楼 wingwing 2009-09-17 从楼主的描述中nonce的字段为32位长,应该是MD5的加密,也就是说长度是等长的,是不是nonce有什么标准的规定?