Authentication

HTTP: The Definitive Guide》阅读笔记。

Authentication means showing some proof of your identify.

当用户访问某些隐私信息时,需要用户提供身份证明,通常就是填写用户名和密码。

Basic Authentication

basic authentication

安全隐患

basic authentication需要结合SSL等技术一起使用以满足安全性的要求。

Digest Authentication

digest authentication

digest

A digest is a “condensation of a body of information”.

实际上就是一个单向映射,将无穷多可能的值映射到某个有限集合中。 譬如MD5,将任意长度的字节映射成128位(的摘要)。

这些映射最重要的特点是,如果不知道密码,需要花费很长的时间才能猜中对应的摘要;知道摘要,需要花费很长时间才能计算出密码。

MD5的128位经常写成32个16进制的字符(每个代表4位)。也就是说,MD5将任意长度的输入映射成32个字符。

摘要本身还不能防止replay攻击,为此,服务器可以传给客户端一个nonce,客户端可以将其连接到密码摘要后面再发给服务器。 由于这个nonce可以变动频繁,或者是每次请求都不一样,即使拿到了这个“摘要:nonce”,也很快便会失效。

digest authentication支持多种算法,RFC 2617中推荐MD5和MD5-sess。默认是MD5

计算公式

KD(H(A1), <nonce>:<nc>:<cnonce>:<qop>:H(A2))

实际中,前面的公式展开后为:

MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))

H与KD

H(d) = MD5(d)
KD(s, d) = MD5(s:d)

A1与A2

请求信息被分为两部分:

RFC 2617定义了两种方式来计算A1


`A2`代表的是消息本身,如URL,请求方法(request method),消息实体(entity body)。
可用来防止消息被恶意篡改。

RFC 2617也定义了两种计算`A2`的方式。
* `qop="auth"`。只包含URL和请求方法。

A2 = :


* `qop="auth-init"`。添加了消息实体。

A2 = ::H()


`qop`即`quality of protection`。

#### nonce
RFC 2617推荐的生成方法:

nonce = BASE64(time-stamp H(time-stamp “:” ETag “:” private-key))

```

time-stamp为时间戳,或是其它不会重复的值。 ETag即对应的请求头值,和请求实体绑定。 private-key是只有服务器知道的秘密。

服务器在收到客户端的Authorization请求头后,重新计算哈希部分(H()), 并检查其是否与Authorization头中的nonce值吻合。

服务器在计算哈希进行对比验证时,需要上次的time-stamp, 可以对Authorization头中的nonce先进行base-64解码,去掉后面32个字符得到。

ETag可从请求头中取得。private-key应该是不变的吧。

其它安全考虑

请求头篡改

digest authentication只对WWW-Authenticate和Authorization请求头进行了一定程度的防护,要想保证其它请求头不被篡改,需要对请求头进行端到端加密或数字签名。

Replay Attacks

blabla

推荐做法是nonce值只对一次transaction有效,且设置timeout

Dictionary Attacks

第三方可以长时间地监听http transaction,搜集nonce/response对,然后用密码推测程序去猜密码。 为了应对这种攻击,最好地策略是使用复杂密码,且定期换密码。

Hostile Proxies and Man-in-the-Middle Attacks

很多请求都经过代理,代理便能进行监听,或者是将认证协议改成basic authentication

这个问题除了使用SSL外,基本无解。

Chosen Plaintext Attacks

客户端利用服务器提供的nonce来计算其response, 所以,代理或服务器便可能在nonce上做手脚来获得密码。

Precomputed dictionary attacks

结合了Dictionary Attacks的特点。 事先利用一些nonce和密码生成对应的response, 然后将这些nonce发给客户端,收到response后再去查,一旦匹配上便知道了密码。

Batched brute-force attacks

与前一种方式的不同之处在于,并不是从事先算好的response中去找匹配, 而是直接根据response去穷举。

此种攻击容易破解,只需要开启cnonce。 这个值是由客户端计算出来的,根据它去计算response便基本防止了从nonceresponse去猜密码的可能性。

Storing Passwords

digest authentication机制将用户的response与服务器存储的信息做对比, 这些信息(通常是用户名,H(A1))一旦被暴露,从前面的公式可以看出,便可以不需要解出密码,而直接根据服务器的nonce去计算response,进行攻击。

这种攻击基本上也是无解的,减轻的方法是:

对比

basic-vs-digest

真正安全的可行方案

真正安全地作法就是使用SSL。