【问题标题】:How to use my own root certificate in iOS Secure Transport API?如何在 iOS 安全传输 API 中使用我自己的根证书?
【发布时间】:2015-07-15 14:54:46
【问题描述】:

我正在尝试在已建立的传输层之上使用Apple's Secure Transport API,并带有我自己的根证书。我的根证书是SecCertificateRef,但我不知道如何使它受信任。

我检查了以下函数,每个函数看起来都非常接近我的需要:

  • SSLAddDistinguishedName() 未实现;
  • SSLSetTrustedRoots() 已弃用;
  • SSLSetCertificateAuthorities() 仅用于客户端身份验证。

如果我可以覆盖SecContextRef 中的SecTrustRef,那么SecTrustSetAnchorCertificates() 就可以完成这项工作。不幸的是,这条途径只让我找到了SSLGetPeerSecTrust(),这似乎是一个Apple私有的API。

【问题讨论】:

    标签: ios security ssl


    【解决方案1】:

    我认为你想要的是以下内容:

    OSStatus status = SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, true);
    

    然后在握手期间

     OSStatus status = SSLHandshake(sslContext);
        if (status == errSSLPeerAuthCompleted)
        {
            SecTrustRef trust = NULL;
            status = SSLCopyPeerTrust(sslContext, &trust);
    
            // Perform your custom trust rules here.  e.g.
            BOOL bTrusted = NO;
            NSArray* anchor = [NSArray arrayWithObject:(id)pCACert];
            OSStatus result = SecTrustSetAnchorCertificates(trust, (CFArrayRef)anchor);
            /* Uncomment this to enable both system certs and the one we are supplying */
            //result = SecTrustSetAnchorCertificatesOnly(trust, NO);
            SecTrustResultType trustResult;
            result = SecTrustEvaluate(trust, &trustResult);
            if (result == errSecSuccess)
            {
              switch (trustResult)
              {
                case kSecTrustResultProceed:
                case kSecTrustResultUnspecified:
                  bTrusted = YES;
                  break;
    
                case kSecTrustResultInvalid:
                case kSecTrustResultDeny:
                case kSecTrustResultRecoverableTrustFailure:
                case kSecTrustResultFatalTrustFailure:
                case kSecTrustResultOtherError:
                default:
                  break;
              }
            }
    
            // If trusted, continue the handshake
            if (bTrusted)
              status = SSLHandshake(sslContext);
            else 
            {
              /* Your trust failure handling here ~ disconnect */
            }
        }
    

    其中 pCAcert 是您希望信任的根证书 (SecCertificateRef)

    【讨论】:

      【解决方案2】:

      如果我理解这一点,您正在尝试:

      {您的应用}--[ssl 会话]--> {您的服务器}

      您的服务器正在使用一些由您自己的 CA(根)签名的证书。您正在尝试通过手机发送 CA 证书并将其用作受信任的 CA,而不是外面的全球 CA。

      这似乎就是你要找的东西:

      准备会议

      1. 调用 SSLNewContext(在 OS X 中)或 SSLCreateContext(在 iOS 和 OS X 中)以 创建一个新的 SSL 会话上下文。

      2. 编写 SSLWrite 和 SSLRead I/O 函数并调用 SSLSetIOFuncs 以 将它们传递给安全传输。

      3. 使用 CFNetwork、BSD 套接字或 Open 建立连接 运输。然后调用 SSLSetConnection 指定连接到 应用 SSL 会话上下文。

      4. 调用 SSLSetPeerDomainName 指定全限定域名 您要连接的对等方的(可选但高度 推荐)。

      5. 调用 SSLSetCertificate 指定要在 身份验证(服务器端需要,客户端可选)。

      OSStatus SSLSetCertificate ( SSLContextRef context, CFArrayRef certRefs );
      

      certRefs
      要设置的证书。此数组包含 SecCertificateRef 类型的项目,但 certRefs[0] 除外,它的类型为 SecIdentityRef。

      讨论 设置证书是强制性的 服务器连接,但对于客户端是可选的。指定一个 客户端证书启用 SSL 客户端身份验证。你 必须在 certRefs[0] 中放置一个 SecIdentityRef 对象,该对象标识 叶证书及其对应的私钥。 指定根 证书是可选的;如果没有指定,根证书 验证此处指定的证书链必须存在于 系统范围的可信锚证书集。

      来自:https://developer.apple.com/library/mac/documentation/Security/Reference/secureTransportRef/

      【讨论】:

      • 我相信SSLSetCertificate() 的目的是让一个设备将其身份和证书链传达给另一个设备。我正在寻找一种方法让客户端指定它信任某个根证书。我会试试你的建议,但我认为这不是我想要的。
      • 我强调说您可以覆盖设备的根证书。
      • 如果他们对客户证书不感兴趣,这是否真的适用于任何人?我试过这样做,但仍然得到CFNetwork SSLHandshake failed (-9810)。你不能指定一个空的certRefs[0],如果我尝试在其中放一个随机证书,它也不起作用。
      猜你喜欢
      • 2022-07-20
      • 2012-04-19
      • 2011-08-10
      • 2017-12-06
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      相关资源
      最近更新 更多