【问题标题】:Alamofire ServerTrustPolicy Certificate Pinning Not Blocking Charles Proxy Swift 3Alamofire ServerTrustPolicy 证书固定不阻止 Charles Proxy Swift 3
【发布时间】:2017-11-01 22:29:50
【问题描述】:

我进行了广泛的搜索,但未能找到我的问题的答案。为了使我们的应用程序更安全,我们被告知要使用“证书固定”。我们已经为所有 API 调用使用了 Alamofire 库,因此使用包含的 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 Proxy 这样的东西工作吗?

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

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

我感谢任何和所有的帮助。提前致谢!

【问题讨论】:

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


    【解决方案1】:

    我将回答我自己的问题,只是因为我想在未来帮助其他人解决同样的问题。当我在上面配置serverTrustPolicies时,你创建了一个String : ServerTrustPolicy的字典,我的错误在于服务器名称的String

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

    我的 url 属性是我们用于 API 的 baseURL,它是 https://www.mycompany.com/api - 这导致了我所有的问题。一旦我将其调整为域www.mycompany.com,固定就按预期工作了!现在,当我在启用了 pinning 的情况下运行 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
    ]
    

    希望这对将来的其他人有所帮助!祝你好运

    【讨论】:

    • 感谢您在此处留下此评论。我有完全相同的问题!
    • 很高兴为您提供帮助! @Forbze
    猜你喜欢
    • 2017-12-06
    • 2015-12-09
    • 2014-07-07
    • 2014-08-14
    • 2016-04-09
    • 2019-06-16
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    相关资源
    最近更新 更多