NSURL *url = [NSURL URLWithString:@"https://localhost:8443/deploy/index.html"]; ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; [request setValidatesSecureCertificate:YES];//set to NO if you use the self-signed certificate如果这个时候你开启验证,则会返回如下错误
A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)
因为我们的证书是自签名,而苹果已经明确提示,你的证书可能是自签名,所以导致失败。SecIdentityRef identity = NULL; SecTrustRef trust = NULL; // SecCertificateRef myReturnedCertificate = NULL; NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]]; // NSLog(@"%@",[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]); [ASIHTTPRequestDemo extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data]; [request setClientCertificateIdentity:identity]; // status = SecIdentityCopyCertificate (identity,&myReturnedCertificate); // [request setClientCertificates:[NSArray arrayWithObject:(id)PKCS12Data]]; [request startSynchronous]; NSError *error = [request error]; if (!error) { //do something } ...... }思路就是读取p12文件,然后将证书内容和证书密钥导出,然后将证书塞入request,随后startSynchronous
+ (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data { OSStatus securityError = errSecSuccess; // NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"" forKey:(id)kSecImportExportPassphrase]; CFStringRef password = CFSTR("1234"); //证书密码 const void *keys[] = { kSecImportExportPassphrase }; const void *values[] = { password }; CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys,values, 1,NULL, NULL); CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); securityError = SecPKCS12Import((CFDataRef)inPKCS12Data,(CFDictionaryRef)optionsDictionary,&items); if (securityError == 0) { CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0); const void *tempIdentity = NULL; tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity); *outIdentity = (SecIdentityRef)tempIdentity; const void *tempTrust = NULL; tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust); *outTrust = (SecTrustRef)tempTrust; } else { NSLog(@"Failed with error code %d",(int)securityError); return NO; } return YES; }
四.RSA服务端加密,客户端解密
根据私钥和csr导出公钥
NSString *pkcsPath = [[NSBundle mainBundle] pathForResource:@"root" ofType:@"p12"]; // 下面的与上面的一样 // NSString *pkcsPath = [[NSBundle mainBundle] pathForResource:@"pkcs-daniate" ofType:@"pfx"]; NSString *certPath = [[NSBundle mainBundle] pathForResource:@"server_public_key" ofType:@"der"]; Security *security = [Security sharedSecurity]; OSStatus status = -1; status = [security extractEveryThingFromPKCS12File:pkcsPath passphrase:@"1234"]; NSLog(@"status = %ld", status); // 取得公钥 status = [security extractPublicKeyFromCertificateFile:certPath]; NSLog(@"status = %ld", status); // 苹果官方文档中只说了短数据加密,但也提到了长数据的分段加密 // 短数据 NSString *plainText = @"This is plain text~中华人民共和国~"; NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; NSData *encrypted = [security encryptWithPublicKey:plainData]; NSData *decrypted = [security decryptWithPrivateKey:encrypted]; // NSString *encryptedText = [[NSString alloc] initWithData:encrypted encoding:NSUTF8StringEncoding]; NSString *decryptedText = [[NSString alloc] initWithData:decrypted encoding:NSUTF8StringEncoding]; // NSLog(@"plainData: %p", plainData); // NSLog(@"encrypted: %p", encrypted); // NSLog(@"decrypted: %p", decrypted); NSLog(@"encrypted: %@",encrypted); NSLog(@"decrypted text: %@", decryptedText);p12文件包含私密,der则是包含公钥,分别提取并且利用其加密解密,从而达到验证的目的。