Привет. Я пытался экспортировать формат открытого ключа в виде сертификата x509 для отправки на сервер.в то время как я генерировал его обычным способом, он работает хорошо, но после попытки добавить формат этой функцией
SecTrustCreateWithCertificates
для открытого ключа происходит сбой!
+(NSDictionary *)generatePublicAndPrivate {
NSMutableDictionary *result = [[NSMutableDictionary alloc]init];
OSStatus status = noErr;
NSMutableDictionary *privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary *publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary *keyPairAttr = [[NSMutableDictionary alloc] init];
NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier length:strlen((const char *)publicKeyIdentifier)];
NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier length:strlen((const char *)privateKeyIdentifier)];
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
[keyPairAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithInt:2048] forKey:(id)kSecAttrKeySizeInBits];
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];
[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];
status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
NSData* publicData = [NSData dataWithBytes:publicKey length:SecKeyGetBlockSize(publicKey)];
NSData* privateData = [NSData dataWithBytes:privateKey length:SecKeyGetBlockSize(privateKey)];
SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)publicData);
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
SecTrustRef trustRef;
OSStatus statusForPublic = SecTrustCreateWithCertificates(certificateRef, policyRef, &trustRef);
NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates failed.");
SecTrustResultType trustResult;
statusForPublic = SecTrustEvaluate(trustRef, &trustResult);
NSAssert(status == errSecSuccess, @"SecTrustEvaluate failed.");
SecKeyRef publicKeyWithX509Certififcate = SecTrustCopyPublicKey(trustRef);
NSAssert(publicKeyWithX509Certififcate != NULL, @"SecTrustCopyPublicKey failed.");
NSData* publicDataWithX509Certificate = [NSData dataWithBytes:publicKey length:SecKeyGetBlockSize(publicKey)];
[result setValue:[publicDataWithX509Certificate base64EncodedStringWithOptions:0] forKey:@"public"];
[result setValue:[privateData base64EncodedStringWithOptions:0] forKey:@"private"];
VALSecureEnclaveValet *oneTimePassword = [[VALSecureEnclaveValet alloc] initWithIdentifier:@"ResalatOneTimePassword" accessControl:VALAccessControlUserPresence];
[oneTimePassword setValue:CFBridgingRelease(privateKey) forKey:@"PrivateKeyObject"];
[oneTimePassword setString:[NSString stringWithFormat:@"%@", [privateData base64EncodedStringWithOptions:0]] forKey:@"OneTimePrivateKey"];
[Functions saveNSUSERData:@"PublicKey" ValueData:[publicData base64EncodedStringWithOptions:0]];
return result;
}