我正在尝试将Google Translate API用于正在构建的简单iOS应用。我基本上只能尝试使用SSL来处理此请求。

根据Google Translate API, it supports SSL。所以现在我的问题是我该怎么办?这是我现在正在尝试的一些代码。我有来自Translation API的API。

func translateRequest(text: String, fromLang: String, toLang: String) {
    let httpsURL = NSURL(string: "https://www.googleapis.com/language/translate/v2?key=<MYAPIKEYHERE>&source=\(fromLang)&target=\(toLang)&q=\(text)&format=text")
    let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    sessionConfiguration.timeoutIntervalForRequest = NSTimeInterval(10)
    let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)
    let translateTask = session.dataTaskWithURL(httpsURL!, completionHandler: completionHandlerTranslate)
    translateTask.resume()
}

func completionHandlerTranslate(dataOpt: NSData?, responseOpt: NSURLResponse?, errorOpt: NSError?) {
    // A helper function to do something with responses
}


现在,由于我使用的是NSURLSession(而不是NSURLConnection),所以我的控制器也由NSURLSessionDelegate提供。根据Apple's docs(在“配置身份验证”部分中),对于NSURLSession我只需要实现didReceiveChallenge功能。该函数的签名是:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {

}


但是我不知道应该去哪里。我已经看到很多人尝试验证服务器的示例,但我仍然感到困惑。

这是我的问题:


SSL用于加密数据,因此要在客户端和服务器之间进行加密的通信,在didReceiveChallenge中我需要做什么?
如何确定didReceiveChallenge拒绝所有其他证书(例如放置像CharlesProxy这样的代理并尝试嗅探数据)?

最佳答案

禁止使用Charles Proxy通常不是一个好主意,因为对于某人使用它来对付别人是不切实际的。它之所以起作用,是因为用户已明确安装了证书,以告知操作系统信任Charles Proxy生成的伪造证书。用户通常喜欢查看您的应用程序在自己的设备上发送的数据的能力,并且阻止他们这样做可能会给人一种印象,即您的应用程序在做一些不可靠的事情。

话虽如此,如果您真的想阻止HTTPS代理正常工作,则可以通过密钥固定来实现。而不是信任证书,而是编写didReceiveChallenge处理程序,该处理程序请求对除服务器信任之外的所有内容进行默认处理。然后,为了获得服务器信任:


从挑战对象中提取提议的凭证。
从凭证的证书链中提取第一个(叶子)证书; IIRC,它的索引为0,但不要在此引用我的名字。
从证书中提取公钥。
在您的应用程序包中的某处添加服务器公钥的副本。
比较两个公钥。如果它们匹配,则以告诉它使用提供的证书的方式返回/调用回调。
如果不匹配,请取消整个连接/任务。


无论如何,这是基本思想。进行此更改后,嗅探流量的唯一方法是替换应用程序捆绑包中的公钥并重新签名应用程序。

08-26 07:07