Alamofire ServerTrustPolicy证书固定不阻止Charles Proxy Swift 3

时间:2017-05-31 23:37:10

标签: ios swift alamofire http-proxy certificate-pinning

我进行了广泛的搜索,但未能找到我的问题的答案。为了使我们的应用程序更安全,我们被告知使用“证书固定”。我们已经将Alamofire库用于所有API调用,因此使用ServerTrustPolicyManager作为实现证书固定的方法似乎很自然。我在我的应用包中添加了适当的证书,这是我用来为Alamofire配置SessionManager的代码:

let url = "https://www.mycompany.com"

var manager: SessionManager? {

    let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
        certificates: ServerTrustPolicy.certificates(),
        validateCertificateChain: true,
        validateHost: true
    )

    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        url: serverTrustPolicy
    ]
    let config = URLSessionConfiguration.default

    return SessionManager(configuration: config, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))

}

现在,当我想要发出API请求时,我有这个方法:

func request(routerRequest request: URLRequestConvertible) -> DataRequest {
    assert(url != "", "A base URL string must be set in order to make request")
    print("URL: \(url) : \(request)")
    return (manager ?? SessionManager.default).request(request)
}

现在我遇到的问题是,当我使用像查尔斯代理这样的东西时,这仍然有效...所有的请求仍在进行中。由于证书不匹配,证书锁定是否应该阻止像Charles Proxy这样的工作?

我测试了其他正确使用证书固定的应用,它们会阻止任何类型的代理(Charles或其他)建立连接。如果我在启用Charles时尝试运行像Uber或我的Wells Fargo银行应用程序的应用程序,每个请求都会被拒绝,我会看到一个错误,上面写着“无法完成请求,ssl证书无效”(这是不是逐字的)。

在配置SessionManager之后,我觉得有一个步骤我不知道了。我阅读并帮助我遇到的大多数文档似乎暗示在配置管理器以启用证书固定后,它应该拒绝任何带有无效证书的请求。谁能帮我?我错过了什么?

我感谢任何帮助。提前谢谢!

1 个答案:

答案 0 :(得分:9)

我将回答我自己的问题,只是因为我希望将来有可能帮助其他人解决同样的问题。当我配置上面的serverTrustPolicies时,您创建了一个String : ServerTrustPolicy的字典,我的错误在String中显示为服务器名称。

let serverTrustPolicies: [String: ServerTrustPolicy] = [
    url: serverTrustPolicy
]

我的url属性是我们用于API的baseURL,它是https://www.mycompany.com/api - 这导致了我的所有问题。一旦我将其调整为域www.mycompany.com,就会像预期的那样工作!现在当我运行Charles Proxy并启用了固定时,我会拒绝所有请求,并且Charles发出错误消息“没有请求,可能是SSL证书被拒绝了。”

我没有进行任何严格的字符串操作,而是将此扩展添加到将来使用 - 如果您有多个baseURL,则需要从中提取域名:

extension String {
    public func getDomain() -> String? {
        guard let url = URL(string: self) else { return nil }
        return url.host
    }
}

现在你可以这样做:

let serverTrustPolicies: [String: ServerTrustPolicy] = [
    url.getDomain() ?? url : serverTrustPolicy
]

希望这有助于将来的其他人!古德勒克