由于 iOS 10 中的错误 nonce-count,HTTP 摘要认证失败

HTTP digest authentication fail due to wrong nonce-count in iOS 10

自从 iOS 10 起,由于授权中的错误 nonce-count,HTTP 摘要身份验证不再适用于我们的应用程序:由 NSURLSession 生成的摘要 header。

相同的代码在 iOS 9 中有效,但在 iOS 10

中无法验证
  1. 使用 NSURLRequest
  2. 创建一个 POST 请求
  3. 用 NSURLSession 触发它
  4. urlSession(_:didReceive:completionHandler:) 委托中处理 NSURLAuthenticationMethodHTTPDigest
  5. 服务器按预期响应 401 和 qop="auth" 字符串
  6. 应用再次请求授权:摘要 header 集。

    根据RFC2617

    nonce-count

    This MUST be specified if a qop directive is sent (see above), and MUST NOT be specified if the server did not send a qop directive in the WWW-Authenticate header field. The nc-value is the hexadecimal count of the number of requests (including the current request) that the client has sent with the nonce value in this request. For example, in the first request sent in response to a given nonce value, the client sends "nc=00000001". The purpose of this directive is to allow the server to detect request replays by maintaining its own copy of this count - if the same nc-value is seen twice, then the request is a replay. See the description below of the construction of the request-digest value.

    但是,即使是 iOS 10 中的第一个请求,nonce-count 从 "nc=00000002" 开始,这会导致服务器拒绝它。

  7. 期望服务器响应 200 OK

iOS 9 及之前:

POST /Tunnel/Message.aspx HTTP/1.1
Host: 172.18.70.12:3454
Accept: */*
Content-Type: application/xml
User-Agent: iViewer/1 CFNetwork/758.5.3 Darwin/15.6.0
Connection: keep-alive
Cookie: 
AuthType: digest
Accept-Language: zh-tw
Content-Length: 69
Accept-Encoding: gzip, deflate
Authorization: Digest username="admin", realm="ND8422P", 
nonce="cc17a78cdd96d54e012eadefe7d13d82", uri="/Tunnel/Message.aspx", 
response="51587db4bcf6eeece68c4ec21108f170", 
cnonce="47b8df8a980f280038834b7817250e90", nc=00000001, qop="auth"
<?xml version="1.0" encoding="UTF-8"?><GetServerInfo></GetServerInfo>

HTTP/1.0 200 OK
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/xml
Content-Length: 1127

iOS 10:

POST /Tunnel/Message.aspx HTTP/1.1
Host: 172.18.70.12:3454
Accept: */*
Content-Type: application/xml
User-Agent: iViewer/1 CFNetwork/808.0.2 Darwin/16.0.0
Connection: keep-alive
Cookie: 
AuthType: digest
Accept-Language: en-us
Content-Length: 69
Accept-Encoding: gzip, deflate
Authorization: Digest username="admin", realm="ND8422P", 
nonce="4b8bf8549da0c3010f031472e95f387d", uri="/Tunnel/Message.aspx", 
response="91cf44bc0aadf2f743164d03b5c708c7", 
cnonce="b5f9e6c69e19c1b396298d68f2aefe7e", nc=00000002, qop="auth"
<?xml version="1.0" encoding="UTF-8"?><GetServerInfo></GetServerInfo>

HTTP/1.0 401 Unauthorized
WWW-Authenticate: Digest qop="auth", realm="ND8422P", nonce="8e8b0538bb08876ac4d8203f1d14e9ac"
CSeq: 0

有人遇到同样的问题吗?

我能找到的唯一相关 post 是: Apple Developer Forums : Problem of the digest authentication,但没有更多信息。

如何在不要求服务器端忽略错误的情况下在客户端应用程序端修复它或获得解决方法nonce-count?

谢谢。

很有可能,OS 首先发送一个 HEAD 请求,而您的服务器端代码没有得到它。我会尝试 运行 Charles Proxy 来验证这是否正在发生。

也就是说,跳过 nonce 计数本身并不表示任何类型的攻击。如果请求以某种方式丢失(例如网络错误),它甚至可能在 iOS 9 中发生。重要的是确保计数不会倒退。所以我认为你的服务器代码有问题,不应该拒绝它。

Apple 开发人员技术支持确认这是 iOS10 的错误。 希望尽快修复。

Thank you for contacting Apple Developer Technical Support (DTS). We believe this issue is a bug. Please file a bug report using the Bug Reporter tool https://developer.apple.com/bug-reporting/.

更新: Apple 在 iOS 10.2 Beta 3

中修复了这个问题

我们公司也有同样的问题,如下所述:

我们可以在 iOS 10 台设备的应用程序和 Safari 浏览器中重现该问题。似乎没有简单的客户端解决方法。我们向 Apple 提交了错误报告。

在我们的案例中,问题已通过 10.2 Beta 版解决。