Преобразование значения необработанного ключа RSA в объект SecKeyRef для шифрования - PullRequest
8 голосов
/ 08 октября 2009

У меня есть значение RSa publicKey в base64, как мне преобразовать в SecKeyRef Object без добавления в связку ключей Могу ли я добавить значение RSA Raw в связку ключей, который не в формате X509 ???

заранее спасибо

Ответы [ 2 ]

2 голосов
/ 31 августа 2010

Следующий код взят из примера CryptoExercise компании Apple в SecKeyWrapper.m. Предполагается, что NSData-объект publicKey является двоичным объектом ASN.1 в кодировке DER, а не в кодировке base-64. Таким образом, вам нужно будет получить декодер base-64 и применить его первым. Вы также можете прочитать это сообщение на форумах разработчиков Apple.

- (SecKeyRef)addPeerPublicKey:(NSString *)peerName keyBits:(NSData *)publicKey {
    OSStatus sanityCheck = noErr;
    SecKeyRef peerKeyRef = NULL;
    CFTypeRef persistPeer = NULL;

    LOGGING_FACILITY( peerName != nil, @"Peer name parameter is nil." );
    LOGGING_FACILITY( publicKey != nil, @"Public key parameter is nil." );

    NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
    NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];

    [peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
    [peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
    [peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
    [peerPublicKeyAttr setObject:publicKey forKey:(id)kSecValueData];
    [peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];

    sanityCheck = SecItemAdd((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&persistPeer);

    // The nice thing about persistent references is that you can write their value out to disk and
    // then use them later. I don't do that here but it certainly can make sense for other situations
    // where you don't want to have to keep building up dictionaries of attributes to get a reference.
    // 
    // Also take a look at SecKeyWrapper's methods (CFTypeRef)getPersistentKeyRefWithKeyRef:(SecKeyRef)key
    // & (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef.

    LOGGING_FACILITY1( sanityCheck == noErr || sanityCheck == errSecDuplicateItem, @"Problem adding the peer public key to the keychain, OSStatus == %d.", sanityCheck );

    if (persistPeer) {
        peerKeyRef = [self getKeyRefWithPersistentKeyRef:persistPeer];
    } else {
        [peerPublicKeyAttr removeObjectForKey:(id)kSecValueData];
        [peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
        // Let's retry a different way.
        sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&peerKeyRef);
    }

    LOGGING_FACILITY1( sanityCheck == noErr && peerKeyRef != NULL, @"Problem acquiring reference to the public key, OSStatus == %d.", sanityCheck );

    [peerTag release];
    [peerPublicKeyAttr release];
    if (persistPeer) CFRelease(persistPeer);
    return peerKeyRef;
}
1 голос
/ 17 января 2014

Если кто-то сталкивается с этим вопросом и ищет ответ Какао:

NSData *privateKeyPEMData = [privateKeyPEM dataUsingEncoding:NSUTF8StringEncoding];
CFArrayRef imported = NULL;
SecKeychainRef importedKeychain = NULL;
OSStatus err = 0;
SecExternalFormat format = kSecFormatOpenSSL;
SecKeyRef privateKey = NULL;

[privateKeyString dataUsingEncoding:NSUTF8StringEncoding];
err = SecItemImport((__bridge CFDataRef)(privateKeyPEMData), (CFStringRef)@"pem", &format, NULL, kNilOptions, kNilOptions, importedKeychain, &imported);
NSLog(@"%@ ERROR: %@", self.class, [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil]);

assert(err == errSecSuccess);
assert(CFArrayGetCount(imported) == 1);
privateKey = (SecKeyRef)CFArrayGetValueAtIndex(imported, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...