iOS MQTT链接-双向认证 和 CFNetwork SSLHandshake failed -9824 错误解决方法
iOS MQTT链接-双向认证 亲测可用
双向认证方法:
让后台生成 ca.crt 和 client.p12文件(client.p12文件由client.crt和client.key合成) 我使用的是服务自签证书
使用命令行把ca.crt转化为ca.der格式
openssl x509 -in ca.crt -out ca.der -outform der
client.crt,client.key合并成p12文件
openssl pkcs12 -export -in client.crt -inkey client.key -out certificate.p12 -name "certificate"
如果服务给的证书是 pem 文件
openssl x509 -in ca.pem -out
ca
.der
-outform der
openssl pkcs12 -export -in client-crt.pem -inkey client-key.pem -out certificate.p12 -name "certificate"
MQTTClient中的的session的双向认证方法:
MQTTSSLSecurityPolicyTransport *transport = [[MQTTSSLSecurityPolicyTransport alloc] init];
transport.host = @"127.0.0.1";
transport.port = 1884;
transport.tls = YES;
NSString *ca = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"]; // 必须是der 格式
NSString *client = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"p12"];//注意不可以用client命名,否则无法获取到文件路径
transport.certificates = [MQTTSSLSecurityPolicyTransport clientCertsFromP12:client passphrase:@"password"];
MQTTSSLSecurityPolicy *securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate];
securityPolicy.allowInvalidCertificates = YES;
securityPolicy.validatesDomainName = NO;
securityPolicy.validatesCertificateChain = NO;
securityPolicy.pinnedCertificates = @[[NSData dataWithContentsOfFile:ca]];
transport.securityPolicy = securityPolicy;
MQTTSession *session = [[MQTTSession alloc] init];
session.transport = transport;
session.certificates = nil; // 注意:这双向认证时必须置空,不然会报9824错误
session.securityPolicy = nil; // 不是必须的
session.delegate = self;
session.willFlag = YES;
session.userName = @"userName";
session.password = @"password";
session.willQoS = MQTTQosLevelAtLeastOnce;
session.willRetainFlag = NO;
session.cleanSessionFlag = YES;
session.willTopic = @"/app/lastwill" ;
NSDictionary *dic = @{@"subject":@"disconnect"};
NSData *data1 = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
session.willMsg = data1;
session.clientId = @"ssid";
[session connect];