zoukankan      html  css  js  c++  java
  • 关于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.用户发一个请求: 
    Http代码  收藏代码
    1. POST /atom.cgi HTTP/1.1  
    2. Host: bob.example.com  
    3. Content-Type: application/atom+xml  
    4.   
    5. <?xml version="1.0" encoding="utf-8"?>  
    6. <entry xmlns="http://purl.org/atom/ns#">  
    7.   <title>My Entry Title</title>   
    8.   <created>2003-12-15T14:43:07Z</created>   
    9.   <content type="application/xhtml+xml" xml:lang="en">   
    10.     <div xmlns="http://www.w3.org/1999/xhtml">  
    11.       <p>Hello, <em>weblog</em> world!</p>  
    12.       <p>This is my third post <strong>ever</strong>!</p>  
    13.     </div>  
    14.   </content>    
    15. </entry>  

    2. 由于没有验证信息,服务器以401来响应: 
    Http代码  收藏代码
    1. HTTP/1.1 401 Unauthorized  
    2. WWW-Authenticate: WSSE realm="foo", profile="UsernameToken"  


    注:还有的文章讲这里服务器生成一个nonce, 然后在下一步附加到Request里,一块参与摘要生成。这个server nonce本身好像没有什么用途,但由于客户端nonce没有生成规则和长度限制(甚至如果服务器不保存以前使用过的,都无法判断是不是每次都一样的),而生成一个server nonce参与生成摘要可以保证摘要的变化性,就是每次都不一致。由于这个nonce是临时生成,一次有效,中间被人截获也无所谓。在验证时,由于是摘要验证,服务器必须保存这个nonce到验证结束,然后再及时清除。不过加了server nonce的限制,必然会使访问服务的客户端访问两次服务器才能真正访问服务,就是不能直接把身份信息附加上,直接访问服务。感觉这个就是标准的摘要验证差不多了,就变成了"请求-响应"模式了。 

    3. 用户输入用户名和密码,并且生成摘要,以UserToken形式发送到服务器: 
    Http代码  收藏代码
    1. POST /atom.cgi HTTP/1.1  
    2. Host: bob.example.com  
    3. Content-Type: application/atom+xml  
    4. Authorization: WSSE profile="UsernameToken"  
    5. X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z"  
    6.   
    7. <?xml version="1.0" encoding="utf-8"?>  
    8. <entry xmlns="http://purl.org/atom/ns#">  
    9.   <title>My Entry Title</title>  
    10.   <created>2003-12-15T14:43:07Z</created>  
    11.   <content type="application/xhtml+xml" xml:lang="en">  
    12.     <div xmlns="http://www.w3.org/1999/xhtml">  
    13.       <p>Hello, <em>weblog</em> world!</p>  
    14.       <p>This is my third post <strong>ever</strong>!</p>  
    15.     </div>  
    16.   </content>  
    17. </entry>  

    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的一种实现? 望知道的哥们姐妹给一些提示。 
  • 相关阅读:
    ASP.NET MVC 重点教程一周年版 第二回 UrlRouting
    ASP.NET MVC 重点教程一周年版 第三回 Controller与View
    DynamicData for Asp.net Mvc留言本实例 下篇 更新
    Asp.net MVC视频教程 18 单选与复选框
    使用ASP.NET MVC Futures 中的异步Action
    ASP.NET MVC RC 升级要注意的几点
    ATL、MFC、WTL CString 的今生前世
    msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义
    关于Windows内存的一些参考文章
    Windows访问令牌相关使用方法
  • 原文地址:https://www.cnblogs.com/zengda/p/4763086.html
Copyright © 2011-2022 走看看