简体   繁体   English

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

[英]Storing RSA public key into iOS keychain using kSecAttrAccessible

So I know that I can store a RSA key into the keychain using my following code: 所以我知道我可以使用以下代码将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];
}

This I can save and retrieve correctly. 这个我可以正确保存和检索。 If I try to set the kSecAttrAccessible value on save: 如果我尝试在保存时设置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];
}

and then trying to retrieve, I get junk. 然后试图检索,我得到了垃圾。 It's junk because when I retrieve it immediately after I save, the inserted value and the retrieved value are different. 它是垃圾,因为当我保存后立即检索它时,插入的值和检索的值是不同的。

Anyone have a code sample or know how to set the accessibility of the keychain item, specifically for an RSA key? 任何人都有代码示例或知道如何设置钥匙串项的可访问性,特别是RSA密钥?

For public knowledge, it turns out that the attributes used to store the data to the keychain needs to be EXACTLY what is used to retrieve the data from the keychain. 为了公众所知,事实证明,用于将数据存储到钥匙串的属性需要完全用于从钥匙串中检索数据。 If you're missing one of the attributes, even though it seems like an attribute needed only for storing (like kSecAttrAccessible ), you'll get the wrong data. 如果您缺少其中一个属性,即使它看起来只是存储所需的属性(如kSecAttrAccessible ),您也会得到错误的数据。 You won't even get a errSecItemNotFound . 你甚至不会得到一个errSecItemNotFound It returns garbage. 它返回垃圾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM