SSL pinning not working (Objective-C, using NSURLSession)

江枫思渺然 提交于 2020-01-03 05:49:08

问题


NOTE: The same SSL pinning on working on Android counterpart application. So did iOS changed something? Are there many number of certificates on the server for my url and they keep rotating everyday?

Questions are:

  1. SSL Pinning can be achieved by certificate pinning only, then why doesn't it work?

  2. If some one has a clear explanation of how to do it using public key? Please explain.

First I want to explain how did I get local certificate. I think it's pretty straight. I just typed in https://ez-pay.io and then I clicked on the lock icon and downloaded the certificate. If you know what I mean. Now I think this could be the problem too. My question is: Is it the right way to download the certificate?

Ok let's assume this is right. I embedded or copy pasted the certificate into my Xcode project.

Now here is the code to fetch remote (server) certificate and compare it with the local one:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler
{
    NSLog(@"SECURITY : didReceiveChallenge");

    // REMOTE CERTIFICATE
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;

    // Evaluate server certificate [Whether the certificate is valid or not] --
    SecTrustResultType result;
    SecTrustEvaluate(serverTrust, &result);
    BOOL isRemoteCertValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);

    // Remote certificate object --
    SecCertificateRef certificateRemote = SecTrustGetCertificateAtIndex(serverTrust, 0);
    // Returns a DER representation of a certificate --
    NSData *remoteCertData = CFBridgingRelease(SecCertificateCopyData(certificateRemote));

    NSData *localCerData = [self GetLocalCertificateData];

    // base 64 encoding of remote certificate --
    NSString* strRemote = [remoteCertData base64EncodedStringWithOptions:0]; // get string from certificate --

    NSString *strLocal = [self  GetLocalCertificateStringForPublicKey];

    // The pinning check -- compare the remote and local certificate data / string --
//    if (isRemoteCertValid && [strLocal isEqualToString:strRemote] )
    if (isRemoteCertValid && [localCerData isEqualToData:remoteCertData] )
    {
        NSLog(@"SECURITY : OK ");
    }
    else
    {
        NSLog(@"SECURITY : FAILS");
        isCertificateValid = false;
    }
}

- (NSData *)GetLocalCertificateData
{
    if ( MODE == PROD_US)
    {
        NSString *pathToCert = [[NSBundle mainBundle]pathForResource:@"prod_ezpay" ofType:@"cer"];
        NSData *localCertificate = [NSData dataWithContentsOfFile:pathToCert];
        return localCertificate;
    }
    else if (MODE == PREP_US)
    {
        NSString *pathToCert = [[NSBundle mainBundle]pathForResource:@"prepEZPAY" ofType:@"cer"];
        NSData *localCertificate = [NSData dataWithContentsOfFile:pathToCert];
        return localCertificate;
    }

    return nil;
}

Now the problem is that comparison of certificates Data always fails:

[localCerData isEqualToData:remoteCertData] // Always false

I have been trying many different approaches checked 5-6 links on google, all have same approach. This project is a bit old, 3-4 years and written in Objective-C.

I tried 3 approaches:

  1. Converting certificates into NSData and compare -- didn't work.

  2. Converting certificate into NSData and then to Base64String -- did not work ..

  3. Also a hack - I printed the data and saved it in string format and hard coded it in the app and then next time onwards keep comparing it with server's certificate data. This approach only works for one day and next day server's certificate data changes. Don't know what is happening.

Please suggest what is wrong in here?

来源:https://stackoverflow.com/questions/59310730/ssl-pinning-not-working-objective-c-using-nsurlsession

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!