내 응용 프로그램에서 certficate를 기반으로 사용자를 인증해야합니다. 이것은 내가하는 방법입니다 1. 우선, 인증서를 샌드 박스로 내 보냅니다. 2. 그런 다음 인증서에서 SecIdentityRef를 추출하고 키 체인에 추가 한 다음 나중에 샌드 박스에서 인증서를 삭제합니다. 3. NSURL 연결의 인증 요청에이 ID를 실제로 전달할 때 의미있는 정보를 제공하지 않고 응용 프로그램이 충돌합니다.정보없이 NSURLCredential이 충돌 함 - 인증서 기반 인증
다음은 모든 관련 코드는 응용 프로그램이 한 번 충돌 내가 NSURLChallenge 보낸 사람이 자격 증명을 전달하는 인증 요청
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate)
{
fprintf(stderr, "identities:\n");
fprintf(stderr, "certificates:\n");
NSLog(@"NSURLAuthenticationMethodClientCertificate");
SecIdentityRef identity;
identity = (__bridge SecIdentityRef)([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]);
SecCertificateRef certificate1 = NULL;
OSStatus *stat = SecIdentityCopyCertificate (identity, &certificate1);
//const void *certs[] = {certificate1};
SecCertificateRef certArray[1] = { certificate1 };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(certificate1);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity
certificates:(__bridge NSArray *)myCerts
persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);
// CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
//
// NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistenceNone];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}
이 자격 증명을 전달
//Exporting the certificate into the app and extracting the identity from it
- (void)importCertificateIntoKeychain:(NSString *)Password
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Certificates"];
NSString *certFolderName = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"CertificatePath"] lastPathComponent]stringByDeletingPathExtension];
NSString *path = [NSString stringWithFormat:@"%@/%@",dataPath,certFolderName];
NSArray*array = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:
path
error:nil];
NSString *thePath;
NSString *fileName;
for (int i=0;i<array.count;i++) {
if ([[array objectAtIndex:i]hasSuffix:@".pfx"]) {
fileName= [array objectAtIndex:i];
thePath = [NSString stringWithFormat:@"%@/%@",path,fileName];
}
}
SecIdentityRef identityApp = nil;
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
NSString *pwd = Password;
CFStringRef password = (CFStringRef)CFBridgingRetain(pwd);
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
CFRelease(options);
CFRelease(password);
if (securityError == errSecSuccess) {
NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate (identityApp, &certificate);
OSStatus status = errSecSuccess;
CFTypeRef persistent_ref = NULL;
const void *keys[] = { kSecReturnPersistentRef, kSecValueRef };
const void *values[] = { kCFBooleanTrue, identityApp };
CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values,
2, NULL, NULL);
status = SecItemAdd(dict, &persistent_ref);
NSLog(@"Status %ld",status);
if (dict)
CFRelease(dict);
[Utils deleteCertificateFromInboxFolder];
} else {
NSLog(@"Error opening Certificate.");
[Utils displayAlertWithTitle:@"Wrong Password" andMessage:@"Error opening certificate"];
}
}
을 니펫입니다.
어떤 도움
이 크게 감사합니다!