iOS 钥匙串:NSDate 与 NSString

Posted

技术标签:

【中文标题】iOS 钥匙串:NSDate 与 NSString【英文标题】:iOS Keychain: NSDate vs NSString 【发布时间】:2017-01-17 00:12:21 【问题描述】:

我想知道在准备Keychain item 时,您什么时候将NSString 转换为NSData

例如: 在本教程提供的代码中 http://hayageek.com/ios-keychain-tutorial/

它声明如下:

[dict setObject:encodedKey forKey:(__bridge id)kSecAttrAccount];

然而,在 David Thiel 的《iOS 应用程序安全》一书中使用了以下内容:

[dict setObject:@"dthiel" forKey:(__bridge id)kSecAttrAccount];

所以,我很困惑,我什么时候需要将NSString 转换为NSData 我怎么知道?

谢谢。

【问题讨论】:

【参考方案1】:

您必须将值编码为 NSData。

例如:

#define KeychainIdentifier @"keychain.access.identifier"

- (void)setKeyValue:(NSString *)key value:(NSString *)value 
    //The keychain identifier must be encoded as `NSData`.
    NSData *keychainItemID = [KeychainIdentifier dataUsingEncoding:NSUTF8StringEncoding];


    //Build the query. We need to QUERY the keychain and check if the item exists.
    //If it does, we will NOT be adding the item in the keychain. Note: You can "overwrite" the data if you want but for this example, I'm going to keep it simple and NOT do that.
    //For this example, the item stored is a "GenericPassword".
    //We will query for the existence of "one" item.
    //This query will only return attributes because we are not FETCHING from the keychain. Just "checking/querying".
    //Finally, the item is accessible when the device is unlocked.
    NSMutableDictionary *query = [@
                                    (id)kSecClass             : (id)kSecClassGenericPassword,
                                    (id)kSecAttrGeneric       : keychainItemID,
                                    (id)kSecMatchLimit        : (id)kSecMatchLimitOne,
                                    (id)kSecReturnAttributes  : (id)kCFBooleanTrue,
                                    (id)kSecAttrAccessible    : (id)kSecAttrAccessibleWhenUnlocked,
                                    (id)kSecAttrAccount       : key
                                     mutableCopy];


    //Query the keychain and get all the item's attributes.
    CFMutableDictionaryRef result = nil;
    OSStatus error = SecItemCopyMatching((__bridge CFMutableDictionaryRef)query, (CFTypeRef *)&result);

    if (error == errSecItemNotFound) 
        //Item does not exist, add it to the keychain.
        //To do that, we turn our query into an "INSERT".
        //That means we need to remove the "return" key because we are no longer fetching/querying and returning attributes. We also have to remove the match limit.
        //We also remove the match limit.
        [query removeObjectForKey:(id)kSecMatchLimit];
        [query removeObjectForKey:(id)kSecReturnAttributes];

        //Now we encode the data to be stored in the keychain and then we submit our "INSERT" to the keychain. This will add the item in the keychain.
        [query setObject:[value dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];

        error = SecItemAdd((__bridge CFMutableDictionaryRef)query, nil);

        if (error == noErr) 
            //Success.
        
        else 
            //Something went wrong.
        
    
    else 
        //Item already exists.
    

【讨论】:

感谢您的样品。只是想知道,是否有必要拥有 kSecAttrGeneric?因为我记得kSecClassGenericPassword只需要kSecClasskSecAttrAccountkSecAttrServer来识别,这样对吗? @KwokPingLau;这不是必要的。它是可选的。如您在此处看到的:***.com/questions/11614047/… kSecClassGenericPassword 的主键是 kSecAttrAccount and kSecAttrService

以上是关于iOS 钥匙串:NSDate 与 NSString的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 上存储身份验证令牌 - NSUserDefaults 与钥匙串?

IOS 中的钥匙串可以与 Windows 中的 DPAPI 相比吗?

IOS 生产发布错误:- 错误 - 证书与配置文件不匹配:默认钥匙串没有身份匹配

NSDate与 NSString long long类型的相互转化

iOS14中的钥匙串功能值得你用下!

iOS NSDate日期的基本使用