Ответ 1
- использование незаявленного идентификатора 'publicTag'
publicTag
- это просто уникальный идентификатор, добавленный к элементам Keychain. В примере с образцом CryptoExercise он определяется как
#define kPublicKeyTag "com.apple.sample.publickey"
static const uint8_t publicKeyIdentifier[] = kPublicKeyTag;
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
- Приведение косвенного указателя на указатель Objective-C на 'CFTypeRef' (aka 'const void *') не разрешено с помощью ARC
Это можно решить, используя временную переменную CFTypeRef
:
CFTypeRef result;
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
}
- Я не хочу создавать запрос или еще что-то, чтобы извлечь ключ из брелка. Я имею его в переменной, и я хочу извлечь его оттуда...
Насколько я знаю, вам нужно временно хранить SecKeyRef в Keychain. SecItemAdd
имеет возможность вернуть добавленный элемент в качестве данных. Из документации:
Чтобы получить данные добавленного элемента как объекта типа
CFDataRef
, укажите ключ типа возвратаkSecReturnData
со значениемkCFBooleanTrue
.
Объединяя все это, следующий код должен делать то, что вы хотите:
- (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey {
static const uint8_t publicKeyIdentifier[] = "com.your.company.publickey";
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
[queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Temporarily add key to the Keychain, return as data:
NSMutableDictionary * attributes = [queryPublicKey mutableCopy];
[attributes setObject:(__bridge id)givenKey forKey:(__bridge id)kSecValueRef];
[attributes setObject:@YES forKey:(__bridge id)kSecReturnData];
CFTypeRef result;
sanityCheck = SecItemAdd((__bridge CFDictionaryRef) attributes, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
// Remove from Keychain again:
(void)SecItemDelete((__bridge CFDictionaryRef) queryPublicKey);
}
return publicKeyBits;
}
Я надеюсь, что это сработает, я не могу проверить это на данный момент.
- Последующие действия: Как я могу экспортировать закрытый ключ в NSData, так как я читал несколько раз, что функция, с которой я пытаюсь работать, работает только для открытых ключей.
Я не знаю.