4

有没有人看到用指纹而不是公钥来固定 Alamofire 的方法?

抱歉,如果这已被回答,我还没有在任何地方看到它。

谢谢

4

3 回答 3

3

这最终变得非常简单。下面的代码可能并不完美,我的真实代码正在做一些额外的检查,但这就是大部分。

.SHA1Fingerprint 是 SecCertificate 上的扩展方法,将其复制到 NSData,然后将其转换为 SHA1。我使用 RNCryptor 来做到这一点,但你可以做到这一点。

isValidFingerprint 只是将结果与我已知的每个指纹进行比较。

这一切都取决于我的静态 Alamofire.Manager。

manager.delegate.sessionDidReceiveChallenge = { session, challenge in
        var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
        var credential: NSURLCredential?

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let host = challenge.protectionSpace.host

            if let serverTrust = challenge.protectionSpace.serverTrust {

                let serverTrustPolicy = ServerTrustPolicy.PerformDefaultEvaluation(validateHost: true)

                if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
                    disposition = .UseCredential
                    credential = NSURLCredential(forTrust: serverTrust)
                } else {
                    disposition = .CancelAuthenticationChallenge
                    return (disposition, credential)
                }

                for index in 0..<SecTrustGetCertificateCount(serverTrust) {
                    if let certificate = SecTrustGetCertificateAtIndex(serverTrust, index) {
                        if let fingerPrint = certificate.SHA1Fingerprint {
                            if isValidFingerprint(fingerPrint)  {
                                return (disposition, credential)
                            }
                        }
                    }
                }
            }
        }
        disposition = .CancelAuthenticationChallenge
        return (disposition, credential)
    }
于 2016-05-15T05:49:29.597 回答
2

斯威夫特 4

我更改了 Bob 的答案,它对我有用,您可以根据您的要求更改验证算法,此代码只是检查固定证书之一是否有效。 这个链接帮助我理解我的问题

private static var Manager : Alamofire.SessionManager = {
    let man = Alamofire.SessionManager()
    man.delegate.sessionDidReceiveChallenge = { session, challenge in
        var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
        var credential: URLCredential?
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let host = challenge.protectionSpace.host

            if let serverTrust = challenge.protectionSpace.serverTrust {

                let serverTrustPolicy = ServerTrustPolicy.performDefaultEvaluation(validateHost: true)
                if serverTrustPolicy.evaluate(serverTrust, forHost: host) {
                    disposition = .useCredential
                    credential = URLCredential(trust: serverTrust)
                } else {
                    disposition = .cancelAuthenticationChallenge
                    return (disposition, credential)
                }
                let fingerPrints = [
                    "AJKSFGSGFR64563RFGY874FG43G784F48FG4F4GF74GF4F7G4FGF4F74F7GFF58Y".lowercased(),
                    "BJKSFGSGFR64563RFGY874FG43G784F48FG4F4GF74GF4F7G4FGF4F74F7GFF58Y".lowercased(),
                    "CJKSFGSGFR64563RFGY874FG43G784F48FG4F4GF74GF4F7G4FGF4F74F7GFF58Y".lowercased()
                ]

                for index in 0..<SecTrustGetCertificateCount(serverTrust) {
                    let cer = SecTrustGetCertificateAtIndex(serverTrust, index)

                    if let certificate = SecTrustGetCertificateAtIndex(serverTrust, index) {
                        let certData = certificate.data
                        let certHashByteArray = certData.sha256()
                        let certificateHexString = certHashByteArray.toHexString().lowercased()

                        if fingerPrints.contains(certificateHexString) {
                            return (disposition, credential)
                        }
                    }
                }
            }
        }
        disposition = .cancelAuthenticationChallenge
        return (disposition, credential)
    }
    return man
}()

对于转换SecTrustGetCertificateAtIndex(serverTrust, index)(这一行let certData = certificate.data)使用这个扩展

import Foundation
public extension SecCertificate {
    public var data: Data {
        return SecCertificateCopyData(self) as Data
    }
}

对于这两行我使用了 CryptoSwift 库,你可以使用 sha1 而不是 sha256,我用 sha256 指纹固定了证书。

let certHashByteArray = certData.sha256()
let certificateHexString = certHashByteArray.toHexString().lowercased()
于 2019-02-19T09:30:54.423 回答
0

我能问一下您为什么尝试固定指纹而不是公钥或证书的原因吗?

根据我的经验,固定的关键点是将某些内容硬编码到您的程序中。

仅供参考: https ://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning

于 2016-05-10T03:45:24.283 回答