核心
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;
}
}