由于错误的nonce,HTTP摘要认证失败

由于NSURLSession生成的Authorization:Digest头中存在错误的nonce-count,因此自iOS 10以后,HTTP摘要认证不再起作用。

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

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

    根据RFC2617:

    随机数数

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

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

  • 预计服务器响应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
    

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

    我能找到的唯一相关帖子是:Apple开发者论坛:摘要认证的问题,但没有进一步的信息。

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

    谢谢。


    Apple开发者技术支持确认这是iOS 10的一个bug。希望它很快就会被修复。

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

    更新:Apple在iOS 10.2 Beta 3中修复了这个问题


    有可能,操作系统首先发送HEAD请求,而你的服务器端代码没有得到它。 我会尝试运行Charles Proxy来验证这是怎么回事。

    也就是说,跳过一个随机数并不是任何形式的攻击。 如果某个请求以某种方式丢失(例如,网络错误),甚至可能在iOS 9中发生。 重要的是确保计数不会倒退。 所以我会争辩说你的服务器代码有问题,不应该首先拒绝。


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

    我们可以在iOS 10设备的应用程序和Safari浏览器中重现问题。 似乎没有简单的客户端解决方法。 我们与Apple一起发布了一个Bug报告。

    链接地址: http://www.djcxy.com/p/22295.html

    上一篇: HTTP digest authentication fail due to wrong nonce

    下一篇: Android Digest Authentication