SSL在Alamofire中使用指纹固定

问题描述 投票:4回答:3

有没有人看到过用指纹代替公钥钉住Alamofire的方法?

对不起,如果已经回答,我还没有在任何地方看到它。

谢谢

alamofire fingerprint pinning
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)
    }

1
投票

斯威夫特4

我改变了鲍勃的回答并且它对我有用,你可以根据你的要求更改你的验证算法,这段代码只是检查一个固定证书是否有效。 this link帮助我理解了我的问题

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 library,你可以使用sha1而不是sha256,我用sha256指纹固定证书。

let certHashByteArray = certData.sha256()
let certificateHexString = certHashByteArray.toHexString().lowercased()

0
投票

我可以问你为什么试图钉指纹而不是公钥或证书吗?

根据我的经验,固定的关键是在程序中硬编码。

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

© www.soinside.com 2019 - 2024. All rights reserved.