2012-07-26 242 views
19

我想將私鑰添加到iOS鑰匙串中。證書(公鑰)工作正常,但私鑰拒絕...我完全困惑爲什麼下面的代碼不起作用。將私鑰添加到iOS鑰匙串

首先我檢查如果當前密鑰(=,所述鑰匙鏈的情況下,密鑰是鍵/值存儲)是鑰匙串「自由」。然後我要添加私鑰。

CFStringRef labelstring = CFStringCreateWithCString(NULL, [key cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8); 

NSArray* keys = [NSArray arrayWithObjects:(__bridge id)kSecClass,kSecAttrLabel,kSecReturnData,kSecAttrAccessible,nil]; 
NSArray* values = [NSArray arrayWithObjects:(__bridge id)kSecClassKey,labelstring,kCFBooleanTrue,kSecAttrAccessibleWhenUnlocked,nil]; 
NSMutableDictionary* searchdict = [NSMutableDictionary dictionaryWithObjects:values forKeys:keys]; 

CFRelease(labelstring); 

NSMutableDictionary *query = searchdict; 


CFTypeRef item = NULL; 
OSStatus error = SecItemCopyMatching((__bridge_retained CFDictionaryRef) query, &item); 

if (error) 
{ 
    NSLog(@"Error: %ld (statuscode)", error); 
} 

if(error != errSecItemNotFound) 
{ 
    SecItemDelete((__bridge_retained CFDictionaryRef) query); 
} 

[query setObject:(id)data forKey:(__bridge id)kSecValueData]; 

OSStatus status = SecItemAdd((__bridge_retained CFDictionaryRef) query, &item); 

if(status) 
{ 
    NSLog(@"Keychain error occured: %ld (statuscode)", status); 
    return NO; 
} 

調試輸出如下:

2012-07-26 15:33:03.772 App[15529:1b03] Error: -25300 (statuscode) 
2012-07-26 15:33:11.195 App[15529:1b03] Keychain error occured: -25299 (statuscode) 

第一錯誤代碼-25300表示errSecItemNotFound。所以這個鍵沒有存儲值。然後,當我嘗試將私鑰添加到鑰匙串時,我得到-25299這意味着errSecDuplicateItem。我不明白。這是爲什麼發生?

有沒有人有一個線索或暗示對此有何看法?

蘋果的錯誤代碼:提前

errSecSuccess    = 0,  /* No error. */ 
errSecUnimplemented   = -4,  /* Function or operation not implemented. */ 
errSecParam     = -50,  /* One or more parameters passed to a function where not valid. */ 
errSecAllocate    = -108, /* Failed to allocate memory. */ 
errSecNotAvailable   = -25291, /* No keychain is available. You may need to restart your computer. */ 
errSecDuplicateItem   = -25299, /* The specified item already exists in the keychain. */ 
errSecItemNotFound   = -25300, /* The specified item could not be found in the keychain. */ 
errSecInteractionNotAllowed = -25308, /* User interaction is not allowed. */ 
errSecDecode     = -26275, /* Unable to decode the provided data. */ 
errSecAuthFailed    = -25293, /* The user name or passphrase you entered is not correct. */ 

謝謝!

更新#1:我已經想通了,它僅適用於第一次。即使數據和密鑰不同,在第一次存儲到鑰匙串後,我無法存儲其他密鑰。

+0

我面對完全一樣的問題。使用SecItemAdd添加第一個密鑰沒有問題,然後任何對SecItemAdd的連續調用都會失敗,並返回errSecDuplicateItem,儘管SecItemCopyMatching返回了errSecItemNotFound。你有沒有找到解決方案呢? – 100grams 2013-01-08 10:47:18

回答

8

下面的代碼爲我工作:

NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; 
[query setObject:(id)kSecClassKey forKey:(id)kSecClass]; 
[query setObject:(id)kSecAttrAccessibleWhenUnlocked forKey:(id)kSecAttrAccessible]; 
[query setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData]; 

//adding access key 
[query setObject:(id)key forKey:(id)kSecAttrApplicationTag]; 


//removing item if it exists 
SecItemDelete((CFDictionaryRef)query); 

//setting data (private key) 
[query setObject:(id)data forKey:(id)kSecValueData]; 

CFTypeRef persistKey; OSStatus status = SecItemAdd((CFDictionaryRef)query, &persistKey); 

if(status) { 
    NSLog(@"Keychain error occured: %ld (statuscode)", status); 
    return NO; 
} 
+0

刪除一個Keychain項目只是爲了添加一個具有相同信息的項目是不好的做法。我不記得具體的原因,但我相信在嘗試這樣做時可能會導致衝突。 – Joey 2014-04-12 06:01:19

+0

我曾與一位在去年的WWDC上從事Keychain工作的蘋果員工談過,他告訴我,實際上他們現在還沒有提供另外一種方法來實現這一點,但他們有一個專用API用於他們將發佈_soon_。 .. – Chris 2014-04-13 07:55:14

+1

我不知道你的意思是克里斯。我有同樣的問題,並能夠修復我的代碼,以正確找到現有的項目。我的問題是我在添加它時將其定義爲可通過iCloud進行同步,但在搜索時沒有在查詢中包括該內容,因此找不到匹配項。我不必刪除並重新添加。 – Joey 2014-04-13 08:14:14

1

很抱歉,但我永遠無法調試代碼。 Apple提供了一些示例代碼(KeychainItemWrapper),它允許您保存一個字符串(我記得)。它在處理鑰匙鏈方面有很大的幫助。 Web上有一個要求是該類的修改版本,但保存和恢復字典(作爲數據對象存檔,這是Apple代碼對字符串的作用)。這可讓您將多個項目保存到鑰匙串的一個界面中。要點是這裏Keychain for NSDictionary/data

+1

謝謝,但它需要存儲爲'kSecClassKey'(和相應的證書作爲'kSecClassCertificate')。我知道Apple提供了這個示例代碼,用於將用戶憑證(但只是字符串)存儲到鑰匙串中。考慮到人們想要驗證一個證書或者使用'kSecClassKey'的附加保護,它不能使用Apple示例代碼或鏈接的方法進行存儲。不過,我想我已經找到了一個解決方案,但必須在我發佈之前對其進行驗證。 – Chris 2012-07-27 05:41:28

+1

根據我的經驗,鑰匙串包裝不允許將多個項目保存到同一個鑰匙串組中。這造成了一些重大的挫折,但一個解決方案可以在這裏找到:http://stackoverflow.com/questions/11055731/ios-save-multiple-passwords-in-keychain?lq=1 – rob 2012-09-27 16:02:22

+0

這很有趣 - 因爲我在做與我的應用程序中的字典並保存電子郵件,密碼和與用戶相關的另一個上下文。但是我修改了蘋果的代碼並不是很多 - 你可以在我的答案中的鏈接中看到它。這是工作代碼,現在有成千上萬的電話(不是數百萬:-() – 2012-09-27 16:53:26