Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在iOS安全传输API中使用我自己的根证书?_Ios_Security_Ssl - Fatal编程技术网

如何在iOS安全传输API中使用我自己的根证书?

如何在iOS安全传输API中使用我自己的根证书?,ios,security,ssl,Ios,Security,Ssl,我正试图在一个已建立的传输层之上使用我自己的根证书。我的根证书是SecCertificateRef,但我不知道如何使它可信 我已经检查了以下函数,每个函数似乎都非常接近我需要的函数: ssladdistinguishedname()未实现 SSLSetTrustedRoots()不推荐使用 SSLSetCertificateAuthorities()仅用于客户端身份验证 如果我可以覆盖SecContextRef中的SecTrustRef,那么SecTrustSetAnchorCertific

我正试图在一个已建立的传输层之上使用我自己的根证书。我的根证书是
SecCertificateRef
,但我不知道如何使它可信

我已经检查了以下函数,每个函数似乎都非常接近我需要的函数:

  • ssladdistinguishedname()
    未实现
  • SSLSetTrustedRoots()
    不推荐使用
  • SSLSetCertificateAuthorities()
    仅用于客户端身份验证

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

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

{你的应用程序}--[ssl会话]-->{你的服务器}

您的服务器正在使用由您自己的CA(根)签名的证书。您正在尝试将您的CA证书与手机一起发送,并将其用作受信任的CA,而不是现有的全局CA

这似乎就是你想要的:

为会议做准备

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

  • 编写SSLWrite和SSLRead I/O函数,并调用SSLSetIOFuncs以 把它们传给安全的运输部门

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

  • 调用SSLSetPeerDomainName以指定完全限定的域名 要连接到的对等方的(可选但高度受限) 推荐)

  • 调用SSLSetCertificate指定要在中使用的证书 身份验证(服务器端需要,客户端可选)

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

    讨论设置一个或多个证书对于 服务器连接,但对于客户端是可选的。指定 客户端证书启用SSL客户端身份验证。你 必须在certRefs[0]中放置一个识别 叶证书及其相应的私钥指定根目录 证书是可选的如果未指定,则根证书 验证此处指定的证书链必须存在于 系统范围的可信锚证书集


    发件人:

    我想你想要的是:

    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)

    我相信
    SSLSetCertificate()
    的目的是让一个设备将其身份和证书链传递给另一个设备。我正在寻找一种方法,让客户端指定它信任某个根证书。我会尝试一下你的建议,但我不认为这是我想要的。我强调了一点,那就是你可以从设备上覆盖根证书。如果有人对客户端证书不感兴趣,这是否真的对他们有效?我尝试过这样做,但仍然得到
    CFNetwork SSLHandshake失败(-9810)
    。您不能指定null
    certRefs[0]
    ,如果我尝试将随机证书放在其中,它也不会起作用。
     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 */
            }
        }