【问题标题】:Storing RSA public key into iOS keychain using kSecAttrAccessible使用 kSecAttrAccessible 将 RSA 公钥存储到 iOS 钥匙串中
【发布时间】:2014-10-17 17:43:00
【问题描述】:

所以我知道我可以使用以下代码将 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 密钥?

【问题讨论】:

  • 我有类似的问题。原来我缺少 kSecAttrKeyClassPublic 属性,即使在其他调用(例如获取密钥引用)中,应用程序标记就足够了。但是对于 SecItemAdd,每个属性都很重要。

标签: ios objective-c keychain


【解决方案1】:

据公众所知,用于将数据存储到钥匙串的属性需要完全用于从钥匙串中检索数据。如果您缺少其中一个属性,即使它看起来像是仅用于存储的属性(如kSecAttrAccessible),您也会得到错误的数据。你甚至不会得到errSecItemNotFound。它返回垃圾。

【讨论】:

  • 有道理,你得到的垃圾可能是数据解密不正确,因为它获得了不正确的可访问属性。
  • @Joe:实际上,关键位是垃圾,而不是数据。如果没有任何属性匹配,该方法应该返回errSecItemNotFound,而不是用坏键假装成功。这里没有涉及数据的内容,只是存储和检索密钥。对我来说,应该添加一个包含所有属性集的键。然后应该使用任何匹配的属性(如搜索)来检索它,而不是要求插入时使用的所有属性。当前的行为鼓励开发人员存储尽可能少的属性的键,以便更容易检索。
猜你喜欢
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 2010-10-21
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多