OGeek|极客世界-中国程序员成长平台

标题: ios - 如何在 Objective-C 或 Swift 上发送带有 .p12 证书的 https 请求 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-11 22:43
标题: ios - 如何在 Objective-C 或 Swift 上发送带有 .p12 证书的 https 请求

我有一个 react-native 项目,我必须为带有 .p12 认证的 https 请求创建 Native 模块,但我从不使用 Objective-C(它有点复杂)或 Swift 我找到了一个带有证书的 https 请求类 it is但我没有使用这个,因为我没有 .h 文件和我的项目文件夹;

MyBridge.h

#import "React/RCTBridgeModule.h"

@interface MyFirstBridge : NSObject <RCTBridgeModule>

@end

MyBridge.m

#import "MyFirstBridge.h"
#import <React/RCTLog.h>

@implementation MyFirstBridge

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(sendGetRequestNSString *)urllocationNSString *)location)
{
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod"GET"];
[request setURL:[NSURL URLWithString:url]];

NSError *error = nil;
NSHTTPURLResponse *responseCode = nil;

NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];

 if([responseCode statusCode] != 200){
    NSLog(@"Error getting %@, HTTP status code %i", url, [responseCode statusCode]);
    return nil;
}

  callback(@[[NSNull null], [[NSString alloc] initWithDataResponseData encoding:NSUTF8StringEncoding]]);
}

@end

它作为基本的 HTTP 获取请求,但是当我尝试 https 服务时,我需要为每个请求固定一个证书。对于这种情况,如何发送 HTTPS 请求?



Best Answer-推荐答案


我猜通过使用 .p12 证书,您指的是在客户端和服务器之间建立相互身份验证。基本上,你必须经过以下步骤(objective-c):

加载证书文件(服务器的根 CA 证书 + 客户端 key 和证书)

rootCertRef 包含 CA 证书(签署服务器证书的 CA 的根证书)

身份 (SecIdentityRef) 包含向服务器验证客户端所需的客户端 key 和证书。

NSData *rootCertData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource”rootCert” ofType”cer”]];
SecCertificateRef rootCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);

NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource“clientCert" ofType"p12"]];
NSArray *item = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys“password", kSecImportExportPassphrase, nil];
SecPKCS12Import((CFDataRef) p12Data , (CFDictionaryRef)dict, (CFArrayRef *)item);
SecIdentityRef identity = (SecIdentityRef)[[item objectAtIndex:0] objectForKeyid)kSecImportItemIdentity];

配置网址(您已经完成了)

// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString"http://google.com"]];

创建 NSURLConnection>> 将委托(delegate)设置为 self 必须实现 NSURLConnectionDelegate 才能进行客户身份验证

// Create url connection and fire request asynchronously
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

在回调 canAuthenticateAgainstProtectionSpace 中启用服务器和客户端身份验证

- (BOOL)connectionNSURLConnection *)connection canAuthenticateAgainstProtectionSpaceNSURLProtectionSpace *)protectionSpace {
  if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    return YES;
  if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate])
    return YES;
  return NO;
}

执行服务器请求的相互认证

-(void) connection:didReceiveAuthenticationChallengeNSURLAuthenticationChallenge *)challenge {

  //Authenticate the server
  if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { // Verify method

    SecTrustRef trust = [[challenge protectionSpace] serverTrust];         // Create trust object
    NSArray *trustArray = [NSArray arrayWithObjects:rootCertRef, nil];   // Add as many certificates as needed
    SecTrustSetAnchorCertificates(trust, (CFArrayRef) trustArray );        // Set trust anchors

    SecTrustResultType trustResult;                                        // Store trust result in this
    SecTrustEvaluate(trust, trustResult);                                  // Evaluate server trust
    if(trust_result == kSecTrustResultUnspecified) {
      NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
      [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
  } else {
    // handle error;
  }

  //Send client identity to server for client authentication
  if([[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil   persistence:NSURLCredentialPersistenceNone];
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
  }
}

关于ios - 如何在 Objective-C 或 Swift 上发送带有 .p12 证书的 https 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55758377/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4