zoukankan      html  css  js  c++  java
  • 小言HTTP Authentication

    什么是Authentication?

    首先解释两个长的非常像、easy混淆的单词,Authentication(鉴定、认证)Authorization(授权)

    Authentication就是要证明你是谁。举个样例。你告诉别人你的名字叫Alice,怎么样让别人确信你就是Alice,这就是Authentication。

    Authorization则是当别人已经相信是你以后。你是不是被允不同意做做某件事儿。比方,当你已经证明了你就是Alice了,你能够查你自己的信用卡刷卡记录,但不能查Bob的刷卡记录,这就是Authorization(当然,假设Alice是Bob的老婆这样的情况除外)。


    这篇博客就主要看看HTTP Authentication究竟是怎么回事。

    然后两种常见的Authentication机制:HTTP Basic和Digest。


    HTTP Basic

    顾名思义,HTTP Basic指的就是最简单的Authentication协议。简单到什么份儿上呢?直接方式告诉server你的username(username)和password(password)。

    这里如果我们的username是Alice,password是123456。


    我们使用curl訪问server

       curl -u Alice:123456 http://kiwiserver.com/secret -v


    request头部:

     GET /secret HTTP/1.1
     Authorization: Basic QWxpY2U6MTIzNDU2
     ...

    我们这里看到发送的request头部中含有Authentication这个字段,其值为Basic QWxpY2U6MTIzNDU2。Basic表示的使用的是HTTP Basic Authentication。而QWxpY2U6MTIzNDU2。则是由“Alice:123456”进行Base64编码以后得到的结果。


    response头部: 

     HTTP/1.1 200 OK
     ...

    由于我们输入的是正确的usernamepassword。所以server会返回200,表示验证成功。假设我们用错误的用户的password来发送请求,则会得到类似例如以下含有401错误的response头部:

     HTTP/1.1 401 Bad credentials
     WWW-Authenticate: Basic realm="Spring Security Application"
     ...


    乍看起来好像HTTP Basic还挺不错的。QWxpY2U6MTIzNDU2已经让人非常难看出来usernamepassword是什么了。可是,我们须要知道Base64编码是可逆的。也就是我们能够通过decode Base64的编码还原username和password。

    在命令行输入例如以下命令:

       echo QWxpY2U6MTIzNDU2 | base64 -D

    得到:

       Alice:123456

    轻松解密。试想。假设一个人通过一定的方法截获了Alice向server发送的请求,那不是非常easy就行得到她的username和password了吗?所以,为了保证用户的安全。我们不会直接通过HTTP的方式使用Basic Authentication。而是会使用HTTPS,这样更安全一些。



    Replay Attack

    通过前面介绍,我们知道了通过可逆的Base64的编码方式不是太靠谱。那我们在发送password之前,将password用不可逆的方式进行编码不就完了吗?

    比方。前面Alice的password是123456,进行MD5编码

       md5 -s 123456

    以后得到的就是

    e10adc3949ba59abbe56e057f20f883e

    这样不就是不可逆的了?恩。即使有一个叫Craig的家伙截获了我向server发送的usernamepassword。他也不知道我的password究竟是什么了。

    的确,Craig拿到e10adc3949ba59abbe56e057f20f883e这个被md5 hash过的password也不知道Alice的password是什么。可是,假设Craig直接拿着这个字符串放在HTTP头部。再发送给server不就OK了?Craig这样就根本不用解密这个password也能装成“Alice”向server通信。

    这就叫做Replay Attack。



    HTTP Digest

    为了避免被坏人使用Replay Attack,一个简单的想法就是。让我们每次向server发送的认证信息都“必须”是不一样的,这样Craig即使拿到了这个认证信息也没有办法进行replay attack了。那怎样让Alice每次向server发送的认证信息都是不一样的。同一时候可以让server知道这就是Alice呢?

    这就引出了Digest Authentication了。

    当Alice初次訪问server时,并不携带password。此时server会告知Alice一个随机生成的字符串(nonce)。然后Alice再将这个字符串与她的password123456结合在一起进行MD5编码,将编码以后的结果发送给server作为验证信息。

    由于nonce是“每次”(并不一定是每次)随机生成的。所以Alice在不同的时间訪问server,其编码使用的nonce值应该是不同的。假设携带的是同样的nonce编码后的结果,server就觉得其不合法。将拒绝其訪问。这样。即使Craig可以截获Alice向server发送的请求,也没有办法使用replay attack冒充成Alice了。


    我们还是能够使用curl来查看这一过程:

       curl -u Alice:123456 http://kiwiserver.com/secret -v --digest


    curl和server通信过程

    curl -------- request1:GET ------->> Server

    curl <<------ response1:nonce ------- Server

    curl ---- request2:Digest Auth ----> Server

    curl <<------- response2:OK --------  Server


    request1头部:
     GET /secret HTTP/1.1
     ...
    请求1中没有包括不论什么username和password信息

    response1头部:
     HTTP/1.1 401
    Full authentication is required to access this resource
     WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA=="
     ...

    当server接收到request1以后。觉得request1没有不论什么的Authentication信息。所以返回401,而且告诉curl nonce的值是MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA

    request2头部:

     GET /secret HTTP/1.1
     Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth",response="fd5798940c32e51c128ecf88472151af"
     ...

    curl接收到server的nonce值以后,就能够把如password等信息和nonce值放在一起然后进行MD5编码,得到一个response值,如前面红色标出所看到的,这样server就能够通过这个值验证Alice的password是否正确。


    response2头部:

     HTTP/1.1 200 OK
     ...


    当我们完毕Authentication以后,假设我们再次使用刚才的nonce值:

       curl -X GET http://kiwisecrect.com/secret -H 'Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication", nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth", response="fd5798940c32e51c128ecf88472151af"' -v

    收到错误信息:

     HTTP/1.1 401 Incorrect response
     WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth", nonce="MTQwMTk4Mjg4MjQ5NjpjZmNiNzI2ZmFlNzA4Nzg3ZDUxNjk2YTEyMTU3OTc0Yg=="


    Digest Authentication比Basic安全,可是并非真正的什么都不怕了。Digest Authentication这样的easy方式easy收到Man in the Middle攻击。

    (待续)

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    DecimalFormat
    flex 分页
    flex 分页
    算法学习——st表
    [USACO07DEC]美食的食草动物Gourmet Grazers
    [ZJOI2005]沼泽鳄鱼 矩阵乘法
    [SCOI2010]序列操作 线段树
    [LNOI2014]LCA
    [AHOI2013]作业 & Gty的二逼妹子序列 莫队
    Linux相关——关于文件调用
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4732447.html
Copyright © 2011-2022 走看看