2011-12-23 131 views
3

我正嘗試使用我的應用程序將RSA私鑰導入鑰匙串。第一次使用SecKeychainImport()導入密鑰時,操作成功,隨後的導入給我一個EINVAL(100022)錯誤。將私鑰導入鑰匙串返回EINVAL錯誤

如果我退出並在兩次導入之間重新啓動應用程序,則不會發生這種情況。我包含下面的源代碼。

CFArrayRef array = (CFArrayRef)[NSMutableArray array]; 

    SecExternalFormat format = kSecFormatUnknown; 

    //We are always storing a private key… 
    SecExternalItemType type = kSecItemTypePrivateKey; 

    SecKeyImportExportParameters params; 

    SecKeychainRef keychain; 

    SecKeychainCopyDefault(&keychain); 

    memset(&params, 0, sizeof(params)); 

    params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; 
    params.flags = kSecKeyNoAccessControl; 
    params.keyUsage = CSSM_KEYUSE_ANY; 
    params.keyAttributes = CSSM_KEYATTR_EXTRACTABLE; 

    err = SecKeychainItemImport((CFDataRef)data, 
             (CFStringRef)@"pem", 
             &format, 
             &type, 
             0, 
             NULL, 
             keychain, 
             &array); 
    if(err == noErr) 
    { 
     //Change the kSecKeyPrintName attribute of the keychain item. 
    } 

    else 
    { 
     //Handle the error by displaying appropriate alert. 
    } 

我缺少什麼明顯?

+0

不宜第六個參數是'&params'代替的NULL? – 2011-12-24 04:23:20

+0

另外,你在哪個操作系統版本上試過? – 2011-12-24 05:54:57

回答

2

嘗試設置params.keyAttribute中的CSSM_KEYATTR_PERMANENT位。在Lion上,如果我明確設置了此屬性,我可以將多個PEM裝甲的RSA私鑰(使用openssl genrsa生成)導入鑰匙串。如果我不這樣做,導入第一個密鑰時我會得到errSecItemNotFound(-25300)。

(不要忘了在生產中部署此代碼之前刪除kSecKeyNoAccessControl。另外,如果你生成密鑰自己,可以考慮使用SecKeyGenerate/SecKeyGenerateSymmetric代替。)