1

我正在嘗試對需要相互認證的服務器進行API調用。 使用和的NodeJS請求庫我可以用下面的代碼什麼是iOS中相互驗證的等效代碼?

var keyFile = '/Users/username/Documents/Certificates/example-key.pem'; 
var certificateFile = '/Users/username/Documents/Certificates/cert.pem'; 
var options = { 
    uri: 'https://myserver.com/apiOne', 
    key: fs.readFileSync(keyFile), 
    cert: fs.readFileSync(certificateFile), 
    headers: { 
     'Content-Type': 'application/json', 
     'Accept': 'application/json', 
     'Authorization': 'Basic ' + new Buffer(userId + ':' + password).toString('base64') 
    }, 
    body: data //JSON body 
}; 
request.postAsync(options) 
    .spread(function (response, body) { 
     res.status(200).json(JSON.parse(body)); 
    }) 
    .catch(function (err) { 
     res.status(400).send(err); 
    }) 

我如何從iOS應用程序打相同的API打API? 我使用下面的代碼,但沒有從服務器

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) { 
    if challenge.protectionSpace.authenticationMethod == "NSURLAuthenticationMethodServerTrust" { 
     let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust) 

什麼密鑰和證書指的是在代碼的NodeJS響應?我如何在iOS中傳遞它們?

+0

我沒有使用此推送通知。我只是想做一個需要相互認證的API調用。 – vivek241

回答

1

首先,您需要將key和cert轉換爲p12文件。 要做到這一點運行以下命令

openssl pkcs12 -export -out new.p12 -inkey example-key.pem -in cert.pem 

它也將提示你輸入密碼。在下面的代碼中使用此創建的p12和密碼的路徑

#pragma mark - Get Identity 
- (SecIdentityRef)getIdentity { 
    SecIdentityRef identity = nil; 
    CFStringRef password = (__bridge CFStringRef)certPassword; //the password that you entered while creating the p12 file 
    const void *keys[] = { kSecImportExportPassphrase }; 
    const void *values[] = { password }; 
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 
    NSData *certData = [NSData dataWithContentsOfFile:certFilePath]; //the path to the p12 file. You can get this from bundle 
    CFArrayRef items = CFArrayCreate(nil, 0, 0, nil); 
    OSStatus status = SecPKCS12Import((__bridge CFDataRef)(certData), options, &items); 
    CFRelease(options); 
    CFRelease(password); 
    if (status == errSecSuccess) { 
     NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items)); 
     CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); 
     identity = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 
    } else { 
     NSLog(@"Error opening Certificate."); 
    } 
    return identity; 
} 

#pragma mark - Get Certificates 
- (CFArrayRef)getCertificates:(SecIdentityRef) identity { 
    SecCertificateRef certificate = nil; 
    SecIdentityCopyCertificate(identity, &certificate); 
    SecCertificateRef certs[1] = { certificate }; 
    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL); 
    return array; 
} 

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { 
    NSString *authMethod = challenge.protectionSpace.authenticationMethod; 
    NSLog(@"auth method %@", authMethod); 
    if ([authMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"] || [authMethod isEqualToString:@"NSURLAuthenticationMethodClientCertificate"]) { 
     SecIdentityRef identity = [self getIdentity]; // Go get a SecIdentityRef 
     CFArrayRef certs = [self getCertificates:identity]; // Get an array of certificates 
     NSArray *myArray = (__bridge NSArray *)certs; 

     NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent]; 
     [challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge]; 
     completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential); 
    } 
} 
相關問題