使用kSecAttrAccessible将RSA公钥存储到iOS钥匙串中

时间:2014-10-17 17:43:00

标签: ios objective-c keychain

所以我知道我可以使用以下代码将RSA密钥存储到钥匙串中:

+ (void)savePublicKeyToKeychain:(NSData *)key tag:(NSString *)tagString deleteExisting:(BOOL)deleteExisting {
    NSData *tag = [SecKeyWrapper getKeyTag:tagString];

    NSDictionary *saveDict = @{
            (__bridge id) kSecClass : (__bridge id) kSecClassKey,
            (__bridge id) kSecAttrKeyType : (__bridge id) kSecAttrKeyTypeRSA,
            (__bridge id) kSecAttrApplicationTag : tag,
            (__bridge id) kSecAttrKeyClass : (__bridge id) kSecAttrKeyClassPublic,
            (__bridge id) kSecValueData : key
    };
    [self saveKeyToKeychain:saveDict tag:tagString deleteExisting:deleteExisting];
}

+ (void)saveKeyToKeychain:(NSDictionary *)saveDict tag:(NSString *)tagString deleteExisting:(BOOL)deleteExisting {
    OSStatus sanityCheck = SecItemAdd((__bridge CFDictionaryRef) saveDict, NULL);
    if (sanityCheck != errSecSuccess) {
        if (sanityCheck == errSecDuplicateItem && deleteExisting) {
            // delete the duplicate and save again
            SecItemDelete((__bridge CFDictionaryRef) saveDict);
            sanityCheck = SecItemAdd((__bridge CFDictionaryRef) saveDict, NULL);
        }
        if (sanityCheck != errSecSuccess) {
            NSLog(@"Problem saving the key to keychain, OSStatus == %d.", (int) sanityCheck);
        }
    }
    // remove from cache
    [keyCache removeObjectForKey:tagString];
}

我可以正确保存和检索。如果我尝试在保存时设置kSecAttrAccessible值:

+ (void)savePublicKeyToKeychain:(NSData *)key tag:(NSString *)tagString deleteExisting:(BOOL)deleteExisting {
    NSData *tag = [SecKeyWrapper getKeyTag:tagString];

    NSDictionary *saveDict = @{
            (__bridge id) kSecClass : (__bridge id) kSecClassKey,
            (__bridge id) kSecAttrKeyType : (__bridge id) kSecAttrKeyTypeRSA,
            (__bridge id) kSecAttrApplicationTag : tag,
            (__bridge id) kSecAttrKeyClass : (__bridge id) kSecAttrKeyClassPublic,
            (__bridge id) kSecAttrAccessible: (__bridge id) kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
            (__bridge id) kSecValueData : key
    };
    [self saveKeyToKeychain:saveDict tag:tagString deleteExisting:deleteExisting];
}

然后尝试检索,我得到了垃圾。它是垃圾,因为当我保存后立即检索它时,插入的值和检索的值是不同的。

任何人都有代码示例或知道如何设置钥匙串项的可访问性,特别是RSA密钥?

1 个答案:

答案 0 :(得分:3)

为了公众所知,事实证明,用于将数据存储到钥匙串的属性需要 完全 用于从钥匙串中检索数据的内容。如果您错过了其中一个属性,即使它看起来只是存储所需的属性(如kSecAttrAccessible),您也会收到错误的数据。你甚至不会得到errSecItemNotFound。它返回垃圾。