钥匙串 - 安全数据存储

4
我正在开发一个应用程序,使用钥匙串实现。我能够创建并将数据保存到钥匙串中。我正在使用苹果提供的Keychain Wrapper classes
根据要求,我必须在钥匙串中实现最佳安全性(安全团队指出了漏洞,例如在越狱设备上可访问)。
有人可以给我指导吗?
2个回答

7

我之前也使用了你提到的同样的封装程序在应用中实现了钥匙串,但是当然进行了许多修改。

基本上,Keychain是非常安全的。根据苹果公司的说法,它是一个加密容器,可以保存多个应用程序的安全信息,这意味着当钥匙串被锁定时,没有人可以访问其受保护的内容。

在iOS中,只有创建钥匙串的应用程序才能访问它。 根据苹果公司的文档,iOS可以选择将其存储在内存或磁盘缓存中。

但是从iOS 4.xx++开始,它只能进行磁盘缓存(不知道为什么),因此总是创建一个sqlite数据库,其中所有与特定标识符相对应的钥匙串数据都被存储。

在已越狱的设备上,Sqlite数据库可能会被黑客攻击。

为了保护钥匙串

1. 在使用方法“SecItemUpdate”和“SecItemAdd”添加或更新钥匙串数据时,添加安全关键字“kSecAttrAccessibleWhenUnlockedThisDeviceOnly”。

2. 例如:

- (void)writeToKeychain
{
    NSDictionary *attributes = NULL;
    NSMutableDictionary *updateItem = NULL;
    OSStatus result;

    if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr)
    {
        updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];

        [updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];

        NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
        [tempCheck removeObjectForKey:(id)kSecClass];

#if TARGET_IPHONE_SIMULATOR
        [tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
#endif

        [updateItem setObject:(id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(id)kSecAttrAccessible];
        result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
        NSAssert( result == noErr, @"Couldn't update the Keychain Item." );
        CFRelease(attributes);
    }
    else
    {
        [keychainItemData setObject:(id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(id)kSecAttrAccessible];
        result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
        NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
    }
}

在添加到钥匙串之前,对数据进行加密。我使用的是AES-128加密。

还要确保用于加密的密钥是RSA密钥(由SSL Web Service发送)。

注意: 钥匙串数据存储在iPhone的/private/var/Keychains/keychain-2.db文件中。

希望这能帮到您。


非常感谢。这解释了我在尝试将kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(id)kSecAttrAccessible设置为密钥链包装器中的“setObject”时遇到的错误。 - Peter B. Kramer

0
    [attributeDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接