Как я могу отправить запрос https с сертификатом .p12 на Objective-C или Swift? - PullRequest
2 голосов
/ 19 апреля 2019

У меня есть реактивный проект, и мне нужно создать собственный модуль для запроса https с сертификацией .p12, но я никогда не использую Objective-C (это немного сложно) или Swift Я нашел класс для запроса https с сертификацией , это , но я не использовал его, потому что у меня нет файла .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(sendGetRequest:(NSString *)urllocation:(NSString *)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] initWithData:oResponseData encoding:NSUTF8StringEncoding]]);
}

@end

Он работает как базовый HTTP запрос получения, но когда я попробовал службу https, мне нужно прикрепить сертификат для каждого запроса. Как я могу отправить HTTPS запрос для этого случая?

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Я полагаю, используя сертификат .p12, вы имеете в виду установление взаимной аутентификации между клиентом и сервером.По сути, вы должны выполнить следующие шаги (target-c):

  • Создать объекты безопасности, необходимые для аутентификации сервера (проверить его подпись на основе сигнатуры корневого CA) и аутентифицировать клиента (предоставитьсертификат клиента на сервер для проверки его подписи).Загрузите файл .cer CA и файл .p12 клиента.
  • Определите ресурс URL, который вы хотите получить, и создайте NSURLConnection
  • Укажите методы аутентификации, которые вы хотите обработать (используяОбратные вызовы NSURLConnectionDelegate)
  • Обработка запроса аутентификации (с использованием обратных вызовов NSURLConnectionDelegate)

Загрузка файлов сертификата (корневой сертификат CA сервера + ключ и сертификат клиента)

rootCertRef содержит сертификат CA (корневой сертификат CA, подписавшего сертификат сервера)

identity (SecIdentityRef) содержит ключ клиента и сертификат, необходимые для аутентификации клиента на сервере.

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] objectForKey:(id)kSecImportItemIdentity];

Настройка URL (вы уже это сделали)

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

Создать NSURLConnection >> установить для делегата self, который должен реализовывать NSURLConnectionDelegate значениебыть в состоянии выполнить аутентификацию клиента

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

Включить аутентификацию сервера и клиента в калlback canAuthenticateAgainstProtectionSpace

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

Выполните взаимную аутентификацию, запрошенную сервером

-(void) connection:didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)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];
  }
}
0 голосов
/ 19 апреля 2019

У меня есть это быстро из-за нехватки времени, я не могу сейчас преобразовать его в target-C, я надеюсь, что вы конвертируете это самостоятельно,

Установить URL Session Delegate тожепри настройке запроса

   fileprivate func SSLCertificateCreateTrustResult(_ serverTrust: SecTrust)->SecTrustResultType {
    let certificate: SecCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
    let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
    var certName = "localServerCert"
    if serverUrl.contains(find: "uniqueNameinURL"){
        certName = "liveServerCert"
    }
    let cerPath: String = Bundle.main.path(forResource: certName, ofType: "der")!
    let localCertificateData = NSData(contentsOfFile:cerPath)!

    let certDataRef = localCertificateData as CFData
    let cert = (SecCertificateCreateWithData(nil, certDataRef))
    let certArrayRef = [cert] as CFArray
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef)
    SecTrustSetAnchorCertificatesOnly(serverTrust, false)
    let trustResult: SecTrustResultType = SecTrustResultType.invalid
    return trustResult
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
        let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
        var localCertificateTrust = SSLCertificateCreateTrustResult(serverTrust)
        SecTrustEvaluate(serverTrust, &localCertificateTrust)
        if localCertificateTrust == SecTrustResultType.unspecified || localCertificateTrust == SecTrustResultType.proceed
        {
            let credential:URLCredential = URLCredential(trust: serverTrust)
            challenge.sender?.use(credential, for: challenge)
            completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))

        } else {
            let properties = SecTrustCopyProperties(serverTrust)
            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
        }
    }
    else
    {
        completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil);
    }
}

ИЛИ вы можете использовать следующий URL

iOS: предварительно установить сертификат SSL в связке ключей - программно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...