我正在使用iOS企业POS应用程序,该应用程序使用https与服务器进行通信。我看过iOS7 GM中的接收SSL错误-不信任“ AddTrust外部CA根”吗?和区别自签名CA和自签名的证书,一般冲刷网页,但我不会在任何地方获得。
该应用程序在使用http或https协议的iOS6.1上运行良好。它也可以在iOS 7GM上通过http正常运行,但不能通过https正常运行-在发送到服务器的第一条消息上失败。在应用程序方面,我通过以下方式处理身份验证挑战:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
forAuthenticationChallenge:challenge];
}
之后,我将回调到:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
不:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
我认为这意味着客户端和服务器成功地协商了连接,达成了加密协议等。不幸的是,尽管返回看起来很成功(就网络堆栈而言),但我却在AMF有效负载中获得了0字节的数据。
这是有趣的部分-在服务器端(JBoss4.2.3),我可以断点并检查包含AMFRequest的httpRequest主体。通过http我总是在体内获得384个字节。通过https,如果客户端是iOS 6.1,我将获得384字节,如果客户端是iOS 7,则将获得0字节。
还有一个数据点。如果我在客户端运行Charles,则可以使用iOS 7模拟器通过https正常运行。我可以在Charles和服务器上看到我的384字节AMFRequest很好。Charles是http代理,但该应用程序对此一无所知,那么为什么插入Charles作为中介却能使其正常工作呢?我已经安装了Charles的证书,所以我认为它正在通过SSL与服务器通信(不确定)。
感谢您的帮助或建议。
更新:我实施了苹果推荐的方法:
- (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
traceMethod();
SecTrustRef trust = challenge.protectionSpace.serverTrust;
NSURLCredential *credential = [NSURLCredential credentialForTrust: trust];
[challenge.sender useCredential: credential
forAuthenticationChallenge: challenge];
}
但其结果与旧的(iOS 5之前的)方式完全相同。
经过大量研究后,我与Apple Developer Tech Support发生了一起事件,并最终做出了解释。
我已经能够确认Apple在iOS 7中进行了更改,将其作为“建议的BEAST攻击对策”,这是针对SSL TLS协议的“中间人”攻击-请参阅CERT上的此文章。
理想的解决方案是将JBoss(Tomcat)ssl连接器更改为使用:
sslProtocol="TLSv1.2"
不幸的是,现有的JBoss4.2.3GA实现无法处理TLSv1.1或TLSv1.2,或处理使用此对策的消息。看来唯一的解决方案是升级JBoss配置。这需要对JBoss进行重大更改-请参阅此JBoss文章。
一种替代方法是重新编写网络方法,以使用较低级别的框架(CFSocketStream代替NSURLConnection)并禁用BEAST对策。这有两个缺点-它重新暴露了安全漏洞,并且它是一个不平凡的实现,需要进行彻底的测试(尤其是模拟网络边缘情况)。
就我而言,假期前的时间不允许如此大的变化。我的客户是一家大型零售商,其IT部门在10月中旬锁定了环境。
也许这些信息会帮助别人。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句