在我的应用程序中,我试图将私钥导入登录钥匙串。 为此,我在字典中创建了所有属性。
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:(__bridge id)kSecAttrKeyTypeRSA
forKey:(__bridge id)kSecAttrKeyType];
[attributes setObject:(__bridge id)kSecAttrKeyClassPrivate
forKey:(__bridge id)kSecAttrKeyClass];
[attributes setObject:[NSNumber numberWithLong:(2048)]
forKey:(__bridge id)kSecAttrKeySizeInBits];
然后使用
为密钥创建一个SecKeyRef。SecKeyRef privateKey = SecKeyCreateFromData((CFDictionaryRef)attributes, (CFDataRef)encodedPrivateKeyData, &error);
由于我将密钥添加到登录钥匙串中,因此我导出了登录钥匙串的路径,并使用SecKeychainOpen为此创建了一个SecKeyChainRef。
NSArray *path = [NSHomeDirectory() pathComponents];
//returns /Users/<username>/Library/...
NSString *keychainPath = [NSString stringWithFormat:@"%@%@/%@%@",path[0],path[1],path[2],@"/Library/Keychains/login.keychain"];
SecKeychainRef keychain = NULL;
OSStatus status = SecKeychainOpen([keychainPath UTF8String],&keychain);
一旦我们拥有了privateKey和keychainRef,我们实际上可以使用
创建一个privateKey的表示形式。CFDataRef exportData = NULL;
status = SecItemExport(privateKey, kSecFormatWrappedPKCS8, 0, &keyParams, &exportData);
要最终添加存储在exportData
中的privateKey,我使用
CFArrayRef outItems = NULL;
status = SecItemImport(exportData, NULL, &dataFormat, &actualType, 0, &keyParams, keychain, &outItems);
SecItemImport出现问题,我在其中获得OSStatus
-25294 errSecNoSuchKeychain - "The specified keychain could not be found"
CSSM Error: Keychain Access CSSM Exception: -2147413737 CSSMERR_DL_DATASTORE_DOESNOT_EXIST
奇怪的是,SecKeychainOpen和SecItemImport函数都使用与登录钥匙串相同的SecKeychainRef,但是应用程序只有在SecKeychainOpen函数期间才能成功找到钥匙串。仅在SecItemImport操作期间失败。由于是保存了许多密码的登录钥匙串,因此我想出一种解决方案,而不必尽可能重置钥匙串。
这是一个孤立的事件,我只在一台Mac上看到过,想弄清楚为什么会发生这种情况。尝试研究此问题时,我遇到了提到ghosted keychain的线程,但我已经确认这次不是这种情况。