步骤:
一)[服务器端要做的:]服务器端生成pxf文件+给乱七八糟设置:
-------- 参考代码如下--------
$cert = New-SelfSignedCertificate -DnsName "自己想" -CertStoreLocation "cert:\LocalMachine\My"
$cert = New-SelfSignedCertificate -DnsName "域名" -CertStoreLocation "cert:\LocalMachine\My"
$pwd = ConvertTo-SecureString -String 'password0A' -Force -AsPlainText
$path = 'cert:\LocalMachine\My' + $cert.thumbprint
Export-PfxCertificate -Cert $cert -FilePath c:\temp\certreaotransaction.pfx -Password $pwd
二)[客户端要做的:]将pfx文件通过openssl转成cer文件
(终端进入pfx文件夹 输入如下指令)
openssl pkcs12 -in cert.pfx -out cert.cer -nodes (会导出一个cer文件)
(注:但这个cer文件是64code编码,objc文件中使用会出现如下图片中错误:caref is nill,需要再准换成DER-encoded X.509 certificate,也就是用下面的代码转成der格式)
openssl x509 -in myCA.crt -inform PEM -out myCA.cer -outform DER(得到:myCA.der)
三)将myCA.der文件添加到xcode项目中
四)info.plist
info.plist 中加入App Transport Security Settings ,Allow Arbitrary Loads设置为YES
五)写代码!先写GET方式 传入https
记得先添加
然后:如下图
六)链接didReceiveChallenge Delegate
代码如下:
- (void)URLSession:(NSURLSession*)session didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge
completionHandler:(void(^)(NSURLSessionAuthChallengeDispositiondisposition,NSURLCredential*_Nullablecredential))completionHandler {
NSLog(@"证书认证");
if([[[challengeprotectionSpace]authenticationMethod]isEqualToString:NSURLAuthenticationMethodServerTrust]) {
do{
//
SecTrustRefserverTrust = [[challengeprotectionSpace]serverTrust];
NSCAssert(serverTrust !=nil,@"serverTrust is nil");
if(nil== serverTrust)
break;/* failed */
/**
*导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA),请替换掉你的证书名称
*/
NSString*cerPath = [[NSBundlemainBundle]pathForResource:@"myCA"ofType:@"der"];//自签名证书
NSData* caData = [NSDatadataWithContentsOfFile:cerPath];
NSCAssert(caData !=nil,@"caCert is nil");
if(nil== caData)
break;/* failed */
SecCertificateRefcaRef =SecCertificateCreateWithData(NULL, (__bridgeCFDataRef)caData);
NSCAssert(caRef !=nil,@"caRef is nil");
if(nil== caRef)
break;/* failed */
////可以添加多张证书
NSArray*caArray =@[(__bridgeid)(caRef)];
NSCAssert(caArray !=nil,@"caArray is nil");
if(nil== caArray)
break;/* failed */
OSStatusstatus =SecTrustSetAnchorCertificates(serverTrust, (__bridgeCFArrayRef)caArray);
NSCAssert(errSecSuccess== status,@"SecTrustSetAnchorCertificates failed");
if(!(errSecSuccess== status))
break;/* failed */
SecTrustResultTyperesult = -1;
//通过本地导入的证书来验证服务器的证书是否可信
status =SecTrustEvaluate(serverTrust, &result);
if(!(errSecSuccess== status))
break;/* failed */
BOOLallowConnect = (result ==kSecTrustResultUnspecified) || (result ==kSecTrustResultProceed);
if(allowConnect) {
NSLog(@"success");
}else{
NSLog(@"error");
}
/* kSecTrustResultUnspecified and kSecTrustResultProceed are success */
if(! allowConnect)
{
break;/* failed */
}
#if0
/* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */
/*since the user will likely tap-through to see the dancing bunnies */
if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)
break;/* failed to trust cert (good in this case) */
#endif
// The only good exit point
NSLog(@"信任该证书");
NSURLCredential*credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
return[[challengesender]useCredential: credential
forAuthenticationChallenge: challenge];
}
while(0);
}
// Bad dog
NSURLCredential*credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,credential);
return[[challengesender]cancelAuthenticationChallenge: challenge];
}