shell,Linux,security,nginx,network,system,http,web,Authentication

HTTP Authentication--Basic,Digest

  HTTP提供一个基于用户的访问权限控制和认证的通用框架.最常用的HTTP认证方式是Basic,此种方案是基于明文传输,安全性相对较低.另外一种常用的认证方式是Digest,消息摘要认证,兼容性差

  HTTP身份验证框架中,服务器可以用来针对客户端的请求发送challenge(质询信息),客户端则可以用来提供身份验证凭证.基于basic质询与应答的工作流程如下:服务器端向客户端返回401(Unauthorized,未被授权的)状态码,并在WWW-Authenticate首部提供如何进行验证的信息,其中至少包含有一种质询方式.之后有意向证明自己身份的客户端可以在新的请求中添加Authorization首部字段进行验证,字段值为身份验证凭证信息.通常客户端会弹出一个密码框让用户填写,然后发送包含有恰当的Authorization首部的请求

<center>
</center>

Basic Authentication

Basic Authentication 核心概念

Basic认证通过核对用户名,密码的方式,来实现用户身份的验证,Basic认证中,最关键的4个要素

  • userid:用户的id,即用户名
  • password:用户口令
  • realm:域,当前认证的保护范围

同一个server中,访问受限的资源多种多样,可以针对不同的资源定义不同的 realm,并且只允许特定的用户访问.不同的用户可以是不同域内的用户,是多对多关系

Basic Authentication 配置实现

  • 用户的账号和口令

    • 虚拟账号:仅用于访问某服务时用到的认证标识
    • 存储:文本文件,SQL数据库,ldap目录存储,nis等
  • 较为简单的配置方式为使用httpd-tools包所提供的htpasswd程序生成用户认证信息,创建第一个用户时使用-c选项,表示创建存放用户认证信息的文件,-m选项表示以md5的方式将用户口令加密存放

    htpasswd -c -m /path/to/htpasswd UserName

    创建第二个及之后的用户时请不要在加-c选项,如加,则覆盖之前的创建的所有

  1. 在httpd中配置

    AuthType Basic
    AuthName "This is for VIP"
    AuthUserFile "/path/to/htpasswd"
    Require valid-user
  2. 在nginx中配置

    location /vip {
        auth_basic "This is for VIP";
        auth_basic_user_file /path/to/htpasswd;
    }

Basic Authentication 实例

Basic认证是如何实现的,一共分4个步骤,假设用户名为admin,口令为manunkind,用户所请求的URI为/admin

用户访问受限资源/admin,请求报文如下

<center>
</center>

服务端返回401要求身份认证
  • 服务端发现/admin为受限资源,于是向用户发送401状态码,要求进行身份认证

<center>
</center>

  • 响应首部中,通过WWW-Authenticate告知客户端,认证的方案是Basic.同时以realm告知认证的范围This is for VIP
用户发送认证请求
  • 用户收到服务端响应后,填写用户名、密码,然后向服务端发送认证请求

<center>
</center>

  • 请求报文如下,Authorization请求首部中,包含了用户填写的用户名,密码

<center>
</center>

服务端验证请求

服务端收到用户的认证请求后,对请求进行验证,验证包含如下步骤

  • 根据用户请求资源的地址,确定资源对应的realm
  • 解析 Authorization 请求首部,获得用户名、密码
  • 判断用户是否有访问该realm的权限
  • 验证用户名、密码是否匹配

验证通过,则返回请求资源,如果验证失败,则返回401要求重新认证,或者返回403(Forbidden)

Basic Authentication 安全性

  • 由于用户ID与密码是是以明文的形式在网络中进行传输的(尽管采用了base64编码,但是base64算法是可逆的)所以基本验证方案并不安全.基本验证方案应与HTTPS/TLS协议搭配使用.假如没有这些安全方面的增强,那么基本验证方案不应该被来用保护敏感或者极具价值的信息

<center>
</center>

  • 如上图,认证过程中所传输的人户名及口令为base64编码,通过解码或者口算的方式,很容易将用户名和口令以人类极为容易读懂的方式呈现出来

Digest Authentication

Digest认证试图解决Basic认证的诸多缺陷而设计,从 HTTP/1.1起就有了Digest认证.Digest 认证同样使用质询/响应的方式(challenge/response),但不同的是,Digest认证不像Basic那样将认证信息以明文方式发送到服务器端

核心概念

  • WWW-Authenticate:服务端发送的认证质询头部
  • Authentication-Info:服务端发送的认证响应头部,包含nextnonce,rspauth响应摘要等
  • realm:域,当前认证的保护范围
  • qop:质量保护,值为authauth-int或[token],auth-int包含对实体主体做完整性校验
  • nonce:服务端产生的随机数,用于增加摘要生成的复杂性,从而增加破解密码的难度,防范中间人与恶意服务器等攻击类型,这是相对于不使用该指令而言的,另外,nonce本身可用于防止重放攻击,用于实现服务端对客户端的认证

RFC 2617建议采用这个随机数计算公式:nonce = BASE64(time-stamp MD5(time-stamp ":" ETag ":" private-key)),服务端可以决定这种nonce时间有效性,ETag(URL对应的资源Entity Tag,在CGI编程中通常需要自行生成ETag和鉴别,可用于鉴别URL对应的资源是否改变,区分不同语言,Session,Cookie等)可以防止对已更新资源版本(未更新无效,故需要设定nonce有效期)的重放请求,private-key为服务端私有key

  • opaque:这是一个不透明的数据字符串,在询问中发送给客户端,客户端会将这个数据字符串再发送回服务端器.如果需要在服务端和客户端之间维护一些状态,用nonce来维护状态数据是一种更容易也更安全的实现方式
  • stale:nonce过期标志,值为true或false
  • algorithm:摘要算法,值为MD5D5-sess或[token],默认为MD5
  • cnonce:客户端产生的随机数,用于客户端对服务器的认证.由于中间人与恶意服务器等攻击方式的存在,导致一个特意选择而非随机唯一的nonce值传给客户端用于摘要的计算成为可能,使得选择性明文攻击可能奏效,最后用户密码泄露.因此与nonce一样,cnonce可用于增加摘要生成的复杂性,从而增加破解密码的难度,也就保证了对服务端的认证
  • nc:当服务端开启qop时,客户端才需要发送nc(nonce-count).服务端能够通过维护nc来检测用当前nonce标记的请求重放.如果相同的nc出现在用当前nonce标记的两次请求中,那么这两次请求即为重复请求.所以对于防止重放攻击而言,除了nonce之外,nc才是最后的保障,因此服务端除了维护用户账号信息之外,还需要维护noncenc的关联状态数据

Digest Authentication 配置实现

Basic配置实现并无太大差异,此处以通过htdigest工具生成用户认证信息文件的简单方式实现Digest Authentication

  • 生成用户认证信息
htdigest -c /path/to/htpasswd "vip" admin

创建第二个及之后的用户时请不要在加-c选项,如加,则覆盖之前的创建的所有

  • httpd中配置
AuthType Digest
AuthName "vip"
AuthDigestProvider file
AuthUserFile "/path/to/htpasswd"
require valid-user
  • 若要在nginx中使用Digest认证,需要重新编译nginx,但很不巧的是,nginx源码中并没有包含此模块,需要额外添加.一个可以启用nginxdigest认证的模块nginx-http-auth-digest,编译时加入此模块即可
auth_digest_user_file /path/to/htpasswd;
auth_digest_shm_size 4m;
    location /vip {
    auth_digest "vip";
    auth_digest_timeout 60s;
    auth_digest_expires 10s;
    auth_digest_replays 20;
}

Digest Authentication 实例

假设用户名为admin,口令为manunkind,用户所请求的URI为/s4lm0x,realm为vip

  • 用户访问受限资源/s4lm0x
  • 服务端返回401要求身份认证

服务器会随着状态码401Authorization Required,返回带WWW-Authenticate首部字段的响应,通过WWW-Authenticate告知客户端,认证的方案是Digest,该字段内包含质询响应方式认证所需的临时质询码(随机数,nonce).首部字段WWW-Authenticate内必须包含realmnonce这两个字段的信息

<center>
</center>

客户端向服务器回送realmnonce这两个值进行认证.nonce是一种每次随返回的401响应生成的任意随机字符串.该字符串通常由Base64编码的十六进制数的组成形式,但实际内容依赖服务器的具体实现

<center>
</center>

接收到401状态码的客户端,返回的响应中包含Digest认证必须的首部字段 Authorization信息.首部字段Authorization内必须包含username,realm,nonce,uriresponse的字段信息.其中,realm nonce就是之前从服务器接收到的响应中的字段,usernamerealm限定范围内可进行认证的用户名

uri(digest-uri)即Request-URI的值,但考虑到经代理转发后Request-URI的值可能被修改因此事先会复制一份副本保存在uri

response也可叫做Request-Digest,存放经过MD5运算后的加密字串,形成响应码

  • 客户端提交用户名与口令进行认证

<center>
</center>

  • 服务器在接收到包含首部字段Authorization请求的服务器,会确认认证信息的有效性,认证通过后则返回包含Request-URI资源的响应,并且这时会在首部字段Authentication-Info写入一些认证成功的相关信息

<center>
</center>

Digest Authentication 安全性

<center>
</center>

在线字典攻击(Online dictionary attacks)
  • 攻击者可以尝试用包含口令的字典进行模拟计算response,然后与窃听到的任何nonce/response对进行对比,若结果一致则攻击成功
中间人(Man in the Middle)
  • 在一次中间人攻击中,一个弱认证方案被添加并提供给客户端,因此你总是应该从多个备选认证方案中选择使用最强的那一个,甚至中间人可能以Basic认证替换掉服务端提供的Digest认证,从而窃取到用户的安全凭证,然后中间人可利用该凭证去响应服务端的Digest质询认证
预先计算字典攻击(Precomputed dictionary attacks)
  • 攻击者先构建(response, password)nonce/response对字典,然后用选择性明文(nonce)攻击的办法来获得相应质询的response,检索字典找到匹配的response则攻击成功
批量式暴力攻击(Batch brute force attacks)
  • 中间人会对多个用户执行选择性明文攻击来搜集相应的responses,通过控制搜集的nonce/response对的数量将会缩短找到第一个password的耗时,这种攻击的应对之策就是要求客户端使用cnonce指令
假冒服务器欺骗(Spoofing by Counterfeit Servers)
  • 对于Basic认证,这种攻击方式更容易奏效,对于Digest认证则更难,但前提是客户端必须知道将要使用的是Digest认证
微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

支付宝扫一扫,向我赞赏

回复

This is just a placeholder img.