核心
1. 怎麼創建 NSMutableDictionary *sslSetting
2.怎麼驗證服務端公鑰
準備:
本人目前使用的 iOS 公私鑰是 p12, 服務端公鑰建議準備.der 文件。本人實驗了多種方式,覺得下面粘的代碼的那種方式最靠譜。
SecIdentityRef identityout; // You can get SecIdentityRef object from *.p12 keystore file. SSL Socket Server will authentication client base on this certificate. At server side, we will add client's certificate to trust manager.
[sslSettings setObject:@0 forKey:GCDAsyncSocketSSLProtocolVersionMax];
[sslSettings setObject:@YES forKey:GCDAsyncSocketManuallyEvaluateTrust]; // This will call a delegate method socket:(GCDAsyncSocket *)sock didReceiveTrust: ...
[sslSettings setObject:[[NSArray alloc] initWithObjects:(__bridge id)(identityout), nil] forKey:GCDAsyncSocketSSLCertificates];
[self.asyncSocket startTLS:sslSettings];
特別需要注意這個
GCDAsyncSocketSSLProtocolVersionMax 這個key,根據實際項目,去develop.apple.com 查找適應你自己的SSL 加密方式。
2. 在
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;這個方法中
+ (BOOL)isEqualTrust:(SecTrustRef)trust
{
NSBundle *bundle = [self getTradeBundle];
NSString *rootCertPath = [bundle pathForResource:@"XXXX" ofType:@"der"];
NSData *rootCertData = [NSData dataWithContentsOfFile:rootCertPath];
OSStatus status = -1;
SecTrustResultType result = kSecTrustResultDeny;
if(rootCertData) {
// 創建信任證書
CFDataRef certData = CFBridgingRetain(rootCertData);
SecCertificateRef cert1;
cert1 = SecCertificateCreateWithData(NULL, certData);
// 設置信任證書
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)[NSArray arrayWithObject:(__bridge id)cert1]);
status = SecTrustEvaluate(trust, &result);
} else {
NSLog(@"local certificates could not be loaded");
return NO;
}
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) {
//成功通過驗證,證書可信
NSLog(@"local certificates is trust");
return YES;
} else {
CFArrayRef arrayRefTrust = SecTrustCopyProperties(trust);
NSLog(@"error in connection occured\n%@", arrayRefTrust);
return NO;
}
}