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

由于NSURLSession生成的Authorization:Digest头中存在错误的nonce-count,自从iOS 10以来,HTTP摘要authentication不再适用于我们的应用程序。

相同的代码适用于iOS 9,但无法在iOS 10中进行authentication

  1. 用NSURLRequest创build一个POST请求
  2. 用NSURLSession启动它
  3. urlSession(_:didReceive:completionHandler:) delegate中处理NSURLAuthenticationMethodHTTPDigest
  4. 服务器按照预期响应401和qop =“auth”string
  5. 应用程序再次请求授权:摘要标题集。

    根据RFC2617 :

    随机数数

    如果发送了一个qop指令(见上),就必须指定这个参数,如果服务器没有在WWW-Authenticate头域中发送一个qop指令,就不能指定。 nc-value是客户端在此请求中使用nonce值发送的请求数(包括当前请求)的hex计数。 例如,在响应给定的nonce值发送的第一个请求中,客户端发送“nc = 00000001”。 该指令的目的是允许服务器通过维护自己的计数副本来检测请求重放 – 如果相同的nc值被看到两次,则该请求是重放。 请参阅下面关于request-digest值构造的描述。

    然而,即使对于iOS 10中的第一个请求,nonce-count从“nc = 00000002”开始,这导致服务器拒绝它。

  6. 预计服务器响应200确定

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 

有没有人面临同样的问题?

我能find的唯一相关的post是: 苹果开发者论坛:摘要authentication的问题 ,但没有进一步的信息。

如何解决这个问题,或者在客户端应用程序方得到解决方法,而不要求服务器端忽略错误的nonce-count?

谢谢。

苹果开发者技术支持确认这是一个iOS 10的错误。希望它会很快被修复。

感谢您联系Apple开发者技术支持(DTS)。 我们认为这个问题是一个错误。 请使用Bug Reporter工具https://developer.apple.com/bug-reporting/提交错误报告&#x3002;

更新:苹果公司在iOS 10.2 Beta 3中解决了这个问题

机会是,操作系统首先发送一个HEAD请求,并且你的服务器端代码没有得到它。 我会尝试运行Charles Proxy来validation这是怎么回事。

也就是说,跳过乱数并不是本质上表示任何forms的攻击。 即使在iOS 9中,如果某个请求丢失了,也可能发生(例如,networking错误)。 重要的是要确保计数不会倒退。 所以我会争辩说,你的服务器代码是越野车,不应该拒绝开始。

我们在这里描述的公司也有同样的问题: 在更新到iOS 10之后,Cordova应用程序无法与Dynamics NAV Web服务(ODATA)连接

我们可以在iOS 10设备的应用程序和Safari浏览器中重现问题。 似乎没有一个简单的客户端解决方法。 我们用苹果公司开了一个Bug Report。

在我们的案例中,这个问题是在10.2 Beta版本中解决的。