我有一个 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-推荐答案 strong>
我猜通过使用 .p12 证书,您指的是在客户端和服务器之间建立相互身份验证。基本上,你必须经过以下步骤(objective-c):
- 创建验证服务器(根据根 CA 签名验证其签名)和验证客户端(向服务器提供客户端证书以验证其签名)所需的安全对象。加载 CA 的 .cer 文件和客户端的 .p12 文件。
- 定义你要检索和创建 NSURLConnection 的 URL 资源
- 指定您要处理的身份验证方法(使用 NSURLConnectionDelegate 回调)
- 处理身份验证质询(使用 NSURLConnectionDelegate 回调)
加载证书文件(服务器的根 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/
|