最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Alamofire certificate pinning MITM - Stack Overflow

programmeradmin3浏览0评论

I have a problem with my evaluate function with Alamofire. It works fine for most cases, but it does not go through the security check. They use a MITM solution, they also pre-installed a cert to the phone, then they sniffed on the web, and my solution did not alert them about the men in the middle. So I'd change this to alert for user installed CAs. Can anybody help me how to do that?

 public final class CertificatePinnerTrustEvaluator: ServerTrustEvaluating {
    
    public init() {}
    
    func setupCertificatePinner(host: String) -> CertificatePinner {
        return CertificatePinner(host: host)
    }
    
    public func evaluate(_ trust: SecTrust, forHost host: String) throws {
        
        let pinner = setupCertificatePinner(host: host)
        
        if !pinner.validateCertificateTrustChain(trust) {
            print("failed: invalid certificate chain!")
            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }
        
        let certificates = pinner.makeCertChain(from: trust)
        
        guard !certificates.isEmpty else {
            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }
        
        try trust.af.performDefaultValidation(forHost: host)
        try trust.af.performValidation(forHost: host)
        
        let serverCertificatesData = Set(trust.af.certificateData)
        let pinnedCertificatesData = Set(certificates.af.data)
        let pinnedCertificatesInServerData = !serverCertificatesData.isDisjoint(with: pinnedCertificatesData)
        if !pinnedCertificatesInServerData {
            throw AFError.serverTrustEvaluationFailed(reason: .certificatePinningFailed(host: host,
                                                                                        trust: trust,
                                                                                        pinnedCertificates: certificates,
                                                                                        serverCertificates: trust.af.certificates))
        }
    }
}

I have a problem with my evaluate function with Alamofire. It works fine for most cases, but it does not go through the security check. They use a MITM solution, they also pre-installed a cert to the phone, then they sniffed on the web, and my solution did not alert them about the men in the middle. So I'd change this to alert for user installed CAs. Can anybody help me how to do that?

 public final class CertificatePinnerTrustEvaluator: ServerTrustEvaluating {
    
    public init() {}
    
    func setupCertificatePinner(host: String) -> CertificatePinner {
        return CertificatePinner(host: host)
    }
    
    public func evaluate(_ trust: SecTrust, forHost host: String) throws {
        
        let pinner = setupCertificatePinner(host: host)
        
        if !pinner.validateCertificateTrustChain(trust) {
            print("failed: invalid certificate chain!")
            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }
        
        let certificates = pinner.makeCertChain(from: trust)
        
        guard !certificates.isEmpty else {
            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }
        
        try trust.af.performDefaultValidation(forHost: host)
        try trust.af.performValidation(forHost: host)
        
        let serverCertificatesData = Set(trust.af.certificateData)
        let pinnedCertificatesData = Set(certificates.af.data)
        let pinnedCertificatesInServerData = !serverCertificatesData.isDisjoint(with: pinnedCertificatesData)
        if !pinnedCertificatesInServerData {
            throw AFError.serverTrustEvaluationFailed(reason: .certificatePinningFailed(host: host,
                                                                                        trust: trust,
                                                                                        pinnedCertificates: certificates,
                                                                                        serverCertificates: trust.af.certificates))
        }
    }
}
Share Improve this question asked Feb 17 at 13:47 kisstajmikisstajmi 2652 silver badges12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

If your pinning is working correctly it doesn't matter if the user has installed their own root trusts, the pin won't match.

For iOS 15 and later I suggest following Apple's directions and using the native pinning provided by the OS. It allows you to pin any certificate in the chain.

For older OSes that need to use Alamofire's pinning, I suggest using Alamofire's built in trust evaluators, as they're tested to work. Adding the cert you want to pin to your app bundle and adding a ServerTrustManager to your Alamofire Session. You can review Alamofire's security documentation here.

发布评论

评论列表(0)

  1. 暂无评论