2013-07-12 23 views
6

Tôi đang cố gắng thêm khóa công khai RSA vào móc khóa iPhone của mình bằng phương pháp SecKeyWrapper addPeerPublicKey:keyBits: của CryptoExercise. Logic của phương pháp này là lần đầu tiên cố gắng thêm khóa vào keychain và nếu nó đã có (sanityCheck==errSecDuplicateItem), nó sẽ cố gắng truy xuất khóa này từ keychain bằng cách gọi SecKeyItemCopyMatching().SecItemCopyMatching trả về giá trị nil mà không có bất kỳ lỗi nào

Đó là chính xác những gì xảy ra trong trường hợp của tôi: chìa khóa đã có trong keychain, vì vậy hãy gọi tới số SecKeyItemAdd() returns errSecDuplicateItem.

Sau đó, nó cố gắng truy xuất khóa hiện có nhưng SecKeyItemCopyMatching() returns 0 (chỉ ra rằng không có lỗi) nhưng tham số thứ hai (peerKeyRef) vẫn không đáng kể.

Làm cách nào có thể? Điều gì là sai với điều này?

Đây là mã của [SecKeyWrapper addPeerPublicKey:keyBits:] từ mẫu CryptoExercise để tham khảo:

- (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:(__bridge id) kSecClassKey forKey:(__bridge id) kSecClass]; 
    [peerPublicKeyAttr setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id) kSecAttrKeyType]; 
    [peerPublicKeyAttr setObject:peerTag forKey:(__bridge id) kSecAttrApplicationTag]; 
    [peerPublicKeyAttr setObject:publicKey forKey:(__bridge id) kSecValueData]; 
    [peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id) kSecReturnPersistentRef]; 

    sanityCheck = SecItemAdd((__bridge 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 == %ld.", sanityCheck); 

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

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

    if (persistPeer) CFRelease(persistPeer); 
    return peerKeyRef; 
} 
+1

Tôi không nghĩ rằng đó là liên quan đến vấn đề của bạn, nhưng có vẻ như truy vấn bạn đang chuyển đến 'SecItemCopyMatching' bao gồm cả' kSecReturnRef' và 'kSecReturnPersistentRef' được đặt thành true. Điều đó sẽ làm cho giá trị được trả về trong 'peerKeyRef' là' CFDictionaryRef' thay vì 'SecKeyRef' mà mã của bạn trông đợi. – bdash

+0

Tôi nhận thấy rằng, nhưng vì đó là cách nó được viết trong mẫu Apple gốc, tôi để nó như thế cho đến khi nó tạo ra một vấn đề. Tôi đã cố gắng để loại bỏ giá trị cũ và nó mang lại kết quả tương tự: không có kết quả nào cả. – Sebastien

Trả lời

4

tôi đã cùng một vấn đề và tôi giả sử bạn cố gắng nhập một khóa RSA mà đã không được xuất khẩu từ một thiết bị iOS.

Lý do có vẻ là định dạng khóa không tương thích - chi tiết iOS mong đợi một số tiêu đề ASN1 KHÔNG được đặt. Tại sao chức năng trả về OK là đối với tôi chỉ giải thích được với một lỗi ...

Kiểm tra mã tại http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/ này là giải pháp đúng đắn và làm việc cho tôi - vì vậy nhờ Chris Luke

+0

Các bạn có ví dụ tương tự cho khóa riêng không? – Turowicz

Các vấn đề liên quan