能否将TrustKit与AFNetworking集成?iOS平台相关建议咨询
Absolutely! You can absolutely integrate TrustKit with AFNetworking on iOS—it’s actually a pretty straightforward setup once you know the right steps. Let me break this down for you with concrete code examples and best practices.
Step 1: Install Dependencies
First, get both libraries into your project. If you’re using CocoaPods, add these lines to your Podfile:
pod 'TrustKit' pod 'AFNetworking'
Run pod install and open the generated .xcworkspace file.
Step 2: Initialize TrustKit
You’ll want to set up TrustKit early in your app’s lifecycle—typically in AppDelegate’s didFinishLaunchingWithOptions method. Here’s how to configure it with public key pinning for your target domain:
Objective-C
#import <TrustKit/TrustKit.h> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Configure TrustKit NSDictionary *trustKitConfig = @{ kTSKSwizzleNetworkDelegates: @NO, // Disable auto-swizzling to avoid conflicts with AFNetworking kTSKPinnedDomains: @{ @"your-api-domain.com": @{ kTSKPublicKeyHashes: @[ @"YOUR_PUBLIC_KEY_HASH_1", @"YOUR_PUBLIC_KEY_HASH_2" // Always include at least two hashes for rollover ], kTSKEnforcePinning: @YES, kTSKIncludeSubdomains: @YES } } }; [TrustKit initSharedInstanceWithConfiguration:trustKitConfig]; return YES; }
Swift
import TrustKit func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let trustKitConfig = [ kTSKSwizzleNetworkDelegates: false, kTSKPinnedDomains: [ "your-api-domain.com": [ kTSKPublicKeyHashes: [ "YOUR_PUBLIC_KEY_HASH_1", "YOUR_PUBLIC_KEY_HASH_2" ], kTSKEnforcePinning: true, kTSKIncludeSubdomains: true ] ] ] as [String: Any] TrustKit.initSharedInstance(withConfiguration: trustKitConfig) return true }
Pro tip: To generate your public key hashes, run this command in your terminal (replace your-api-domain.com with your actual domain):
openssl s_client -connect your-api-domain.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
Step 3: Hook TrustKit into AFNetworking
Next, you need to tell AFNetworking to use TrustKit’s certificate validation logic instead of its default one. Here’s how to configure your AFHTTPSessionManager (or AFURLSessionManager) instance:
Objective-C
#import <AFNetworking/AFNetworking.h> #import <TrustKit/TrustKit.h> // Initialize your AFNetworking manager AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // Get TrustKit's pinning validator TSKPinningValidator *validator = [[TrustKit sharedInstance] pinningValidator]; // Configure a custom security policy for AFNetworking AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; securityPolicy.validatesDomainName = YES; securityPolicy.allowInvalidCertificates = NO; securityPolicy.validatesCertificateChain = YES; // Replace AFNetworking's default evaluation with TrustKit's securityPolicy.evaluationBlock = ^BOOL(SecTrustRef trust, NSString *domain) { return [validator evaluateTrust:trust forDomain:domain]; }; // Assign the policy to your manager manager.securityPolicy = securityPolicy;
Swift
import AFNetworking import TrustKit let manager = AFHTTPSessionManager() let validator = TrustKit.sharedInstance().pinningValidator let securityPolicy = AFSecurityPolicy(pinningMode: .none) securityPolicy.validatesDomainName = true securityPolicy.allowInvalidCertificates = false securityPolicy.validatesCertificateChain = true securityPolicy.evaluationBlock = { trust, domain in guard let domain = domain else { return false } return validator.evaluate(trust, forDomain: domain) } manager.securityPolicy = securityPolicy
Best Practices & Troubleshooting
- Avoid auto-swizzling: We set
kTSKSwizzleNetworkDelegatestoNObecause AFNetworking manages its own network delegates—auto-swizzling can cause unexpected conflicts. - Rollover support: Always include at least two public key hashes. This lets you update your server’s certificate without breaking existing app installations.
- Handle pinning failures: Listen for TrustKit’s pinning failure notification to log issues or alert users:
Objective-C
[[NSNotificationCenter defaultCenter] addObserverForName:kTSKNotificationPublicKeyPinningFailed object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { NSDictionary *userInfo = note.userInfo; NSString *domain = userInfo[kTSKNotificationDomainKey]; NSString *failureReason = userInfo[kTSKNotificationFailureReasonKey]; NSLog(@"Pinning failed for domain %@: %@", domain, failureReason); // Add user-facing alert logic here if needed }];
Swift
NotificationCenter.default.addObserver(forName: NSNotification.Name(kTSKNotificationPublicKeyPinningFailed), object: nil, queue: .main) { note in guard let userInfo = note.userInfo, let domain = userInfo[kTSKNotificationDomainKey] as? String, let failureReason = userInfo[kTSKNotificationFailureReasonKey] as? String else { return } print("Pinning failed for domain \(domain): \(failureReason)") // Show an alert to the user here }
- Development vs Production: In development, you can set
kTSKEnforcePinningtoNOto bypass pinning if you’re using a self-signed certificate. Always enable enforcement for production builds.
This setup is battle-tested and used in many production iOS apps—once you’ve got the hashes right and the policy configured, it should work seamlessly.
内容的提问来源于stack exchange,提问作者mary

