6

目前我正在开发一个使用相互身份验证以便与 REST 接口通信的应用程序。因为我对这个话题很陌生,所以我研究了几个例子——现在我有一些问题。我希望我能够将所有知识片段拼凑在一起,以便更好地了解整个过程。

该过程应如下所示:

  1. 我得到了包含服务器公钥的导出服务器证书,并将其添加到应用程序包(稍后用于 SSL Pinning)。
  2. 第一个请求,代表 2 路身份验证的开始,是一个发布请求,它还包含一个证书签名请求以获取客户端证书(需要与 REST 接口的安全部分进行对话)。CSR 是通过 openSSL 库在代码中动态生成的。
  3. 服务器的响应返回用于客户端身份验证的签名证书。此证书采用 DER 格式和 Base64 编码。

我用来为第一个请求执行 SSL 固定的代码如下所示,并且 SSL 固定按预期工作。

- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server-cert" ofType:@"cer"];
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);

    NSData *remoteCertificateData =   CFBridgingRelease(SecCertificateCopyData(certificate));
    NSData *localCertificateData = [NSData dataWithContentsOfFile:cerPath];


    if ([remoteCertificateData isEqualToData:localCertificateData]) {

        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];

        [[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:[challenge protectionSpace]];

        NSLog(@"Certificate Pinning Succeeded");

    } else {

        [[challenge sender] cancelAuthenticationChallenge:challenge];

        NSLog(@"Certificate Pinning Failed");

    }
}

但是我该如何处理从服务器返回的证书呢?据我所知,我必须使用以下 NSURLConnection 委托方法 - 并以某种方式将此证书提供给服务器(用于进一步请求)。

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:   (NSURLProtectionSpace *)protectionSpace
{
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {

        NSLog(@"Wants to Authenticate Server Trust");

        return YES;
    }

    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate]) {

        NSLog(@"Wants to Authenticate Client Certificate");

        return YES;
    }

    return NO;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

现在我的问题。我看到了几个使用 PKCS12 格式(需要私钥和证书颁发机构)而不是 DER 编码证书的示例,以针对服务器验证自我。但是,如何在 `didReceiveAuthenticationChallenge 中使用我的 DER 格式的签名证书来获取更多请求?还有一个 Android 应用程序使用相同的过程进行相互身份验证,并且不需要 PKCS12 证书。

会很高兴一些提示。谢谢。

4

0 回答 0