Delphi iOS应用钥匙链存储键值对遇kSecParam错误求助
Delphi iOS 钥匙链存储 kSecParam 错误解决及优化方案
问题根源分析
你的代码触发kSecParam错误的核心原因如下:
kSecValueData参数类型不匹配:该字段要求传入NSData类型,但你传入了NSString(StrToNSStr(Value)),不符合钥匙链的参数规范。- 缺少必填属性字段:使用
kSecClassGenericPassword类型时,必须指定kSecAttrService来标识应用服务,否则钥匙链无法识别条目归属。 - 无效内存操作:你注释了
Data变量的创建代码,但仍在finally块执行CFRelease(Data),会引发野指针问题。
修正后的完整代码
function SaveToKeychain(const Key, Value: string): Boolean; var query: NSMutableDictionary; status: OSStatus; valueData: NSData; serviceStr, accountStr: NSString; begin Result := False; try query := TNSMutableDictionary.Create; try // 将字符串转为UTF-8编码的NSData valueData := TNSData.Wrap(TNSData.alloc.initWithBytes(TEncoding.UTF8.GetBytes(Value), Length(Value) * SizeOf(Byte))); try // 配置钥匙链条目核心属性 query.setValue((kSecClassGenericPassword as ILocalObject).GetObjectID, kSecClass); // 设置唯一服务标识(必填,区分不同应用/服务的钥匙链条目) serviceStr := StrToNSStr('YourAppUniqueService'); query.setValue((serviceStr as ILocalObject).GetObjectID, kSecAttrService); // 设置存储的键值(即传入的Key) accountStr := StrToNSStr(Key); query.setValue((accountStr as ILocalObject).GetObjectID, kSecAttrAccount); // 设置存储的数值(NSData类型) query.setValue((valueData as ILocalObject).GetObjectID, kSecValueData); // 执行钥匙链添加操作 status := SecItemAdd((query as ILocalObject).GetObjectID, nil); AddToLog(Format('SaveToKeychain status: %d', [status])); Result := (status = errSecSuccess); finally valueData.Release; serviceStr.Release; accountStr.Release; end; finally query.Release; end; except on E: Exception do AddToLog('Error in SaveToKeychain: ' + E.Message); end; end;
Delphi 中的 SecureStorage 等效方案
Delphi FireMonkey 提供了简化的钥匙链封装,你可以引入FMX.Platform单元,使用TKeyChain类实现类似 Maui SecureStorage 的便捷操作;也可以使用第三方库DelphiKeychain,避免直接调用底层API的繁琐。
内容的提问来源于stack exchange,提问作者Nicolas Bourgogne
相关产品推荐
相关产品推荐

