Alamofire ServerTrustPolicy 证书固定不阻止 Charles 代理 Swift 3
Alamofire ServerTrustPolicy Certificate Pinning Not Blocking Charles Proxy Swift 3
我进行了广泛的搜索,但未能找到我的问题的答案。为了使我们的应用程序更安全,我们被告知使用 "certificate pinning"。我们已经为所有 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 代理这样的东西时它仍然有效......所有请求仍在进行中。证书固定不应该阻止诸如 Charles 代理之类的东西因为证书不匹配而无法工作吗?
我已经测试了其他正确使用证书固定的应用程序,它们会阻止任何类型的代理(Charles 或其他)建立连接。如果我在启用 Charles 的情况下尝试 运行 Uber 或我的 Wells Fargo 银行应用程序之类的应用程序,则每个请求都会被拒绝,并且我会看到一个类似 "Couldn't complete request, ssl certificate is invalid" 的错误(这不是逐字的) .
我觉得在配置 SessionManager
后缺少一个步骤。我读过和帮助过的大多数文档似乎都暗示,在将管理器配置为启用证书固定后,它应该拒绝任何证书无效的请求。谁能帮我?我错过了什么?
感谢所有帮助。提前致谢!
我要回答我自己的问题,只是因为我想在未来帮助其他人解决同样的问题。我在上面配置serverTrustPolicies
时,你创建了一个String : ServerTrustPolicy
的字典,我的错误在于服务器名称String
。
let serverTrustPolicies: [String: ServerTrustPolicy] = [
url: serverTrustPolicy
]
我的 url
属性 是我们用于 API 的 baseURL,它是 https://www.mycompany.com/api
- 这导致了我所有的问题。一旦我将其调整为域 www.mycompany.com
,固定就如预期的那样工作了!现在,当我 运行 启用固定的 Charles 代理时,我的所有请求都被拒绝了,并且 Charles 发出了一个错误消息 "No request was made, possibly the SSL Certificate was rejected."
我不必进行任何严肃的字符串操作,而是添加此扩展以供将来使用 - 如果您有多个 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
]
希望这对以后的其他人有所帮助!祝你好运
我进行了广泛的搜索,但未能找到我的问题的答案。为了使我们的应用程序更安全,我们被告知使用 "certificate pinning"。我们已经为所有 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 代理这样的东西时它仍然有效......所有请求仍在进行中。证书固定不应该阻止诸如 Charles 代理之类的东西因为证书不匹配而无法工作吗?
我已经测试了其他正确使用证书固定的应用程序,它们会阻止任何类型的代理(Charles 或其他)建立连接。如果我在启用 Charles 的情况下尝试 运行 Uber 或我的 Wells Fargo 银行应用程序之类的应用程序,则每个请求都会被拒绝,并且我会看到一个类似 "Couldn't complete request, ssl certificate is invalid" 的错误(这不是逐字的) .
我觉得在配置 SessionManager
后缺少一个步骤。我读过和帮助过的大多数文档似乎都暗示,在将管理器配置为启用证书固定后,它应该拒绝任何证书无效的请求。谁能帮我?我错过了什么?
感谢所有帮助。提前致谢!
我要回答我自己的问题,只是因为我想在未来帮助其他人解决同样的问题。我在上面配置serverTrustPolicies
时,你创建了一个String : ServerTrustPolicy
的字典,我的错误在于服务器名称String
。
let serverTrustPolicies: [String: ServerTrustPolicy] = [
url: serverTrustPolicy
]
我的 url
属性 是我们用于 API 的 baseURL,它是 https://www.mycompany.com/api
- 这导致了我所有的问题。一旦我将其调整为域 www.mycompany.com
,固定就如预期的那样工作了!现在,当我 运行 启用固定的 Charles 代理时,我的所有请求都被拒绝了,并且 Charles 发出了一个错误消息 "No request was made, possibly the SSL Certificate was rejected."
我不必进行任何严肃的字符串操作,而是添加此扩展以供将来使用 - 如果您有多个 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
]
希望这对以后的其他人有所帮助!祝你好运