如何在Swift中将证书固定到NSURLSession?
该OWASP网站只包含Objective-
C和NSURLConnection的一个例子。
Swift 3+ 更新:
只需定义一个委托类NSURLSessionDelegate
并实现didReceiveChallenge函数( 此代码改编自Objective-c
OWASP示例
):
class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
// Adapted from OWASP https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#iOS
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
if let serverTrust = challenge.protectionSpace.serverTrust {
let isServerTrusted = SecTrustEvaluateWithError(serverTrust, nil)
if(isServerTrusted) {
if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {
let serverCertificateData = SecCertificateCopyData(serverCertificate)
let data = CFDataGetBytePtr(serverCertificateData);
let size = CFDataGetLength(serverCertificateData);
let cert1 = NSData(bytes: data, length: size)
let file_der = Bundle.main.path(forResource: "certificateFile", ofType: "der")
if let file = file_der {
if let cert2 = NSData(contentsOfFile: file) {
if cert1.isEqual(to: cert2 as Data) {
completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust))
return
}
}
}
}
}
}
}
// Pinning failed
completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
}
}
(您可以在此处找到Swift
2
的Gist-
从初始答案开始)
然后使用创建.der
网站的文件openssl
openssl s_client -connect my-https-website.com:443 -showcerts < /dev/null | openssl x509 -outform DER > my-https-website.der
并将其添加到xcode项目。仔细检查列表中的Build phases
标签中是否存在该标签Copy Bundle Resources
。否则,将其拖放到此列表中。
最后在代码中使用它来发出URL请求:
if let url = NSURL(string: "https://my-https-website.com") {
let session = URLSession(
configuration: URLSessionConfiguration.ephemeral,
delegate: NSURLSessionPinningDelegate(),
delegateQueue: nil)
let task = session.dataTask(with: url as URL, completionHandler: { (data, response, error) -> Void in
if error != nil {
print("error: \(error!.localizedDescription): \(error!)")
} else if data != nil {
if let str = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) {
print("Received data:\n\(str)")
} else {
print("Unable to convert data to text")
}
}
})
task.resume()
} else {
print("Unable to create NSURL")
}
OWASP网站只包含Objective-C和NSURLConnection的示例。
问题内容: 我有一个NSURLSession调用dataTaskWithRequest以这种方式发送POST请求 响应等于: 我的问题是我不知道如何获取名称为MYCOOKIEIS的“ Set-Cookie”中的cookie。 我将在用户登录时使用它,因此,如果用户未登录->登录(调用登录api),否则请转到主屏幕并调用其他API。 有人可以帮助我从那里拿走饼干吗? 问题答案: Swift呈现形式可
我想我需要创建一个新的SSL套接字工厂?此外,我不想使用全局SSL上下文(https://github.com/square/okhttp/issues/184)因为显而易见的原因。 谢谢! 编辑: 从 okhttp 2.1.0 开始,您可以非常轻松地固定证书。 请参阅此处的源代码以开始使用
问题内容: 在集成到更大的应用程序之前,我正在尝试测试一个概念验证的命令行应用程序。我想要做的是使用此示例使用NSURLSession下载一些数据。但是,如果使用简单的OS X命令行应用程序中给出的示例,则该应用程序将在检索数据之前退出。 如何使用NSURLSession从独立的命令行应用程序下载数据?我所读的内容是使用NSRunLoop,但是我还没有在Swift中找到明确的示例,因此,如果NSR
问题内容: 我正在尝试解析JSON但收到此错误: 在没有更多上下文的情况下,表达类型不明确 我的代码是: 在没有尝试捕获的情况下,在Xcode 6.4中可以正常工作,但是在Xcode 7中则无法工作。 问题答案: 不要为已解码对象声明类型,因为您希望它是an,并且您正在执行转换来做到这一点。 另外,最好将零选项用于NSJSONSerialization而不是随机选项。 在我的示例中,我还使用了一个
问题内容: 我已经尝试过搜索,但是找不到我的问题的答案。 我正在从github玩这个应用程序:https : //github.com/Yalantis/Koloda/tree/master/Example 我之所以使用它,是因为我正在做一个项目,该项目将使用此应用程序中基于图块的滑动。 我也在使用Firebase。到目前为止,我可以将用户添加到数据库中,因此应用程序和firebase已连接。 我