• 关于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的一种实现? 望知道的哥们姐妹给一些提示。 
  • 相关阅读:
    博客园的界面设置
    ARM 汇编指令集
    winfroms更换皮肤
    面向对象的七项设计原则
    S2-01
    机票查询与订购系统
    重点语法
    第二章
    一、17.09.13
    习作
  • 原文地址:https://www.cnblogs.com/zengda/p/4763086.html
Copyright © 2020-2023  润新知