加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ios – Xcode中的证书固定

发布时间:2020-12-14 19:38:08 所属栏目:百科 来源:网络整理
导读:我得到了证书 pinning in Android的代码 CertificatePinner certificatePinner = new CertificatePinner.Builder().add("publicobject.com","sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=").add("publicobject.com","sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=").add("public
我得到了证书 pinning in Android的代码

CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("publicobject.com","sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
.add("publicobject.com","sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
.add("publicobject.com","sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
.add("publicobject.com","sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
.build();

如何使用NSURLSession方法在IOS中实现相同的任务?

这里有一些参考代码

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust,0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
if ([remoteCertificateData isEqualToData:localCertData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}

编辑部分

我得到了以下解决方案,在NSURLSession中自动调用委托函数,有人可以解释它是如何工作的吗?还需要发送乘数证书我该怎么做?

(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,NSURLCredential * _Nullable))completionHandler
{
    NSString *authMethod = [[challenge protectionSpace] authenticationMethod];

    if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {

        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
    } else {
        SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
        SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust,0);
        NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"];
        NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
        NSURLCredential *credential;

        if ([remoteCertificateData isEqualToData:localCertData]) {
             credential = [NSURLCredential credentialForTrust:serverTrust];
            [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
        }
        else {
            [[challenge sender] cancelAuthenticationChallenge:challenge];
        }



        completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
        NSLog(@"Finished Challenge");
    }
}

解决方法

如果身份验证方法是NSURLAuthenticationMethodServerTrust,则if块会跳过证书固定.我不太确定你为什么这样做 – 你必须查看你获得这段代码片段的来源,看看它的要求是什么.

如果身份验证方法是其他任何内容,则else块执行证书固定.

变量serverTrust从服务器发送到SSL事务状态.这里的主要内容是它有一系列证书来验证服务器.在下一行中,证书设置为链中的叶证书,即服务器的证书.

remoteCertificateData本质上是一个大的二进制blob,表示证书中的信息.内存管理需要调用CFBridgingRelease(所有CFxxx函数都是C/C++函数,而不是Objective-C,并且内存管理比正常情况稍微复杂一点).

localCertData是证书本地副本中信息的二进制blob.请注意,iOS应用程序(或多或少)是一组文件,包括可执行文件以及各种资源等.作为构建过程的一部分,您可以安排将服务器证书的副本包含在该集合中(NSBundle) )文件. cerPath变量设置为证书本地副本的文件路径.

最后,我们检查两个二进制blob是否相等.如果没有,那么来自服务器的证书是假的,我们不继续处理该请求.

我不完全确定你的意思是“需要发送乘数证书”.从您引用的Java代码判断我假设你想要将服务器证书与多个本地证书进行比较.在这种情况下,某些(大致)如下所示(注意:未经测试的代码):

SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
   SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust,0);
   NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));

   BOOL match = NO;
   NSURLCredential *credential;

   for (NSString *path in [[NSBundle mainBundle] pathsForResourcesOfType:@"cer" inDirectory:@"."]) {
          NSData *localCertData = [NSData dataWithContentsOfFile:path];

          if ([remoteCertificateData isEqualToData:localCertData]) {
              credential = [NSURLCredential credentialForTrust:serverTrust];
              match = YES;
              break;
          }
   }       

   if (match) {
      [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
   } else {
      [[challenge sender] cancelAuthenticationChallenge:challenge];
   }

   completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
   NSLog(@"Finished Challenge");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读