【问题标题】:Swift 3 How to validate server certificate using SSL Pinning and AlamoFire?Swift 3 如何使用 SSL Pinning 和 AlamoFire 验证服务器证书?
【发布时间】:2017-03-31 00:55:27
【问题描述】:

我正在用 swift 3 编写一个需要与我的服务器通信的应用程序。我拥有 der 和 crt 格式的完整证书链,我是 CA 的(不要与自签名混淆)。如何在我的应用程序中使用它来验证我的服务器?以下是我的休息电话和回复

休息电话:

var request = URLRequest(url: URL(string: "https://myserver/login")!)
    request.addValue("Content-Type", forHTTPHeaderField: "application/json")
    request.httpMethod = "GET"
    let session = URLSession.shared

    session.dataTask(with: request) {data, response, err in         
        print("=========================DATA===============================")
        if data != nil {
            print(data!)
        }
        print("=========================RESPONSE===============================")
        if response != nil {
            print(response!)
        }
        print("=========================ERR===============================")
        if err != nil {
            print(err!)
        }
        }.resume()

输出:

=========================DATA===============================
=========================RESPONSE===============================
=========================ERR===============================
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x60800011f020>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7fae4803d200) s: myserver i: MySubCA>",
"<cert(0x7fae48047000) s: MySubCA i: MyRootCA>",
"<cert(0x7fae48044600) s: MyRootCA i: MyRootCA>"
), NSUnderlyingError=0x60800005a040 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x60800011f020>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fae4803d200) s: myserver i: MySubCA>",
"<cert(0x7fae48047000) s: MySubCA i: MyRootCA>",
"<cert(0x7fae48044600) s: MyRootCA i: MyRootCA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://myserver/login, NSErrorFailingURLStringKey=https://myserver/login, NSErrorClientCertificateStateKey=0}

【问题讨论】:

    标签: ios rest ssl certificate swift3


    【解决方案1】:

    我很简单地利用在线博客、AlamoFire 和 openssl 解决了这个问题。

    我在 iOS 上使用AlamoFire 进行联网。

    我使用了一篇关于SSL pinning on iOS 的文章来找到正确的方向。

    我使用 openssl 将我的证书转换为 der 格式。

    Der通过openssl转换。

    openssl x509 -in cert.crt -out cert.der -outform DER
    

    您需要将 der 格式的证书添加到您的应用程序包中。

    Swift 3 实现

    // Your hostname and endpoint
    let hostname = "YOUR_HOST_NAME"
    let endpoint = "YOUR_ENDPOINT"
    let cert = "YOUR_CERT" // e.g. for cert.der, this should just be "cert"
    
    // Set up certificates
    let pathToCert = Bundle.main.path(forResource: cert, ofType: "der")
    let localCertificate = NSData(contentsOfFile: pathToCert!)
    let certificates = [SecCertificateCreateWithData(nil, localCertificate!)!]
    
    // Configure the trust policy manager
    let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
        certificates: certificates,
        validateCertificateChain: true,
        validateHost: true
    )    
    let serverTrustPolicies = [hostname: serverTrustPolicy]
    let serverTrustPolicyManager = ServerTrustPolicyManager(policies: serverTrustPolicies)
    
    // Configure session manager with trust policy
    afManager = SessionManager(
        configuration: URLSessionConfiguration.default,
        serverTrustPolicyManager: serverTrustPolicyManager
    )
    
    
    afManager.request(endpoint, method: .get).responseJSON { response in
        debugPrint("All Response Info: \(response)")
    }
    

    【讨论】:

    • 很好解释。喜欢它!
    • 如何在swift中获取.der证书在日期之后无效。
    • 我也喜欢这些链接。不错的分享。所有信息都可用。我希望本着分享的精神对此进行扩展。
    • 是否可以在同一个地方添加 .pem 证书
    • @GRamiReddy,如果您在命令中使用cert.pem 代替cert.crt 来获取DER 格式,它仍然有效。那是openssl x509 -in cert.pem -out cert.der -outform DER
    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 2017-05-18
    • 2010-09-09
    • 2012-11-14
    • 2015-06-24
    • 1970-01-01
    • 2014-03-30
    • 2023-03-04
    相关资源
    最近更新 更多