2009-10-08 13 views

cevap

2

Aşağıdaki kod SecKeyWrapper.m de, Apple'ın CryptoExercise örnekten gelir içinde

teşekkürler. "PublicKey" NSData nesnesinin, kodlanmış base-64 değil, ikili DER kodlu ASN.1 nesnesi olduğunu varsayar. Bu yüzden bir 64 taban kod çözücüsünü almanız ve önce onu uygulamanız gerekir. Apple Developer Forumlarında this post'u da okumak isteyebilirsiniz.

- (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

durumda birisi bu soruya rastlar ve Kakao cevap arıyor:

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); 
İlgili konular