在iOS中执行SSL请求

时间:2016-11-20 16:32:49

标签: ios ssl nsurlsession google-translate

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

根据Google Translate API, it supports SSL。所以现在我的问题是我怎么做到这一点?这是我正在尝试的一些代码。我有一个来自翻译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使用我的控制器。根据{{​​3}}(在“配置身份验证”部分中),NSURLSession我只需要实现didReceiveChallenge功能。该功能的签名是:

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

}

但我不知道该怎么做。我见过许多人试图验证服务器等的例子,但我仍然感到困惑。

以下是我的问题:

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

1 个答案:

答案 0 :(得分:0)

防止使用Charles Proxy通常不是一个好主意,因为对某人使用它对其他人来说并不实际。它只能起作用,因为用户已明确安装证书,以告诉操作系统信任Charles Proxy生成的假证书。用户通常喜欢能够查看您的应用在自己的设备上发送的数据,并阻止他们这样做,这可能会让您觉得您的应用正在做一些阴暗的事情。

话虽如此,如果确实希望阻止HTTPS代理工作,那么您使用密钥固定的方式就是这样做。您可以编写一个didReceiveChallenge处理程序来代替信任证书,该处理程序请求除服务器信任之外的所有内容的默认处理。然后,对于服务器信任:

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

无论如何,这是基本的想法。通过此更改,嗅探流量的唯一方法是替换应用包中的公钥并重新签名该应用。