SecItemAdd返回-50(无效参数):钥匙链存储值失败问题排查
解决SecItemAdd返回错误码-50(无效参数)的问题
你的代码返回-50错误,核心问题是针对kSecClassKey类型的条目,你传入的参数不符合要求,具体来说是kSecValueRef的用法错误。下面分两种场景给你修正方案:
场景1:你只是想存储普通字符串(比如"MyKeyValue")到钥匙链
如果你的需求是存储一个简单的字符串值,那不该用kSecClassKey——这个类型是用来存储加密密钥(SecKeyRef类型)的,不是普通字符串。你应该改用kSecClassGenericPassword,同时把kSecValueRef换成kSecValueData:
NSData* keyData = [@"MyKeyValue" dataUsingEncoding:NSUTF8StringEncoding]; NSData* tagData = [@"com.example.MyKey" dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary* addQuery = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrApplicationTag: tagData, (__bridge id)kSecValueData: keyData }; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addQuery, NULL);
这样修改后,参数就符合要求了,应该能成功存储。
场景2:你确实需要存储一个加密密钥(SecKeyRef)到钥匙链
如果你的目标是存储密钥对象,那kSecValueRef必须传入SecKeyRef类型的实例,而不是原始的NSData。比如你需要先把原始数据转换成SecKeyRef(通常是生成或导入密钥),再传入:
// 假设你已经有了一个SecKeyRef实例(比如通过SecKeyCreateWithData生成) NSData* keyData = [@"MyKeyValue" dataUsingEncoding:NSUTF8StringEncoding]; NSData* tagData = [@"com.example.MyKey" dataUsingEncoding:NSUTF8StringEncoding]; // 示例:将NSData导入为对称密钥(实际场景请根据密钥类型调整参数) CFDictionaryRef attributes = (__bridge CFDictionaryRef) @{ (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeAES, (__bridge id)kSecAttrKeySizeInBits: @256, (__bridge id)kSecAttrApplicationTag: tagData }; SecKeyRef keyRef = SecKeyCreateWithData((__bridge CFDataRef)keyData, attributes, NULL); if (keyRef) { NSDictionary* addQuery = @{ (__bridge id)kSecClass: (__bridge id)kSecClassKey, (__bridge id)kSecAttrApplicationTag: tagData, (__bridge id)kSecValueRef: keyRef }; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addQuery, NULL); CFRelease(keyRef); // 记得释放引用 }
额外注意点
- 钥匙链操作的参数类型必须严格匹配,不同的
kSecClass对应不同的必填参数,混用会直接返回-50错误。 - 如果你不确定自己需要哪种类型,大部分存储普通字符串/数据的场景都用
kSecClassGenericPassword就可以。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

