有没有人看到过用指纹代替公钥钉住Alamofire的方法?
对不起,如果已经回答,我还没有在任何地方看到它。
谢谢
这最终非常直接。下面的代码可能不完美,我的真实代码正在进行一些附加检查,但这是其中的大部分内容。
.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)
}
斯威夫特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()
我可以问你为什么试图钉指纹而不是公钥或证书吗?
根据我的经验,固定的关键是在程序中硬编码。
仅供参考:https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning