iOS Keychain 不会添加带有硬编码字符串的查询

iOS Keychain won't add queries with hardcoded strings

我正在按照 Apple 文档向位于此处的钥匙串添加密码 -> https://developer.apple.com/documentation/security/keychain_services/keychain_items/adding_a_password_to_the_keychain

当我 运行 以下代码时,它按预期工作并且状态返回为 0。

        let credentials = Credentials(username: "testUserName", password: "testPassword")
        let server = "www.example.com"
        let account = credentials.username
        let password = credentials.password.data(using: String.Encoding.utf8)!
        let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
                                    kSecAttrAccount as String: account,
                                    kSecAttrServer as String: server,
                                    kSecValueData as String: password]

        let status = SecItemAdd(query as CFDictionary, nil)
        print(status)

当我修改带有硬编码字符串的代码时,它失败了,状态为 -50。

        let credentials = Credentials(username: "testUserName", password: "testPassword")
        let server = "www.example.com"
        //let account = credentials.username
        //let password = credentials.password.data(using: String.Encoding.utf8)!
        let account = "testUserName"
        let password = "testPassword"
        let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
                                    kSecAttrAccount as String: account,
                                    kSecAttrServer as String: server,
                                    kSecValueData as String: password]

        let status = SecItemAdd(query as CFDictionary, nil)
        print("Keychain Save Status: \(status)")

谁能给我解释一下?我还尝试使用 let account = "testUsername".utf8 将字符串显式设置为 utf8 格式。如果值是有效字符串,这将失败对我来说没有意义。

还有人有状态码描述的 link 吗?我找到了描述,但没有给出相关的数字代码 https://developer.apple.com/documentation/security/1542001-security_framework_result_codes

是的,我在另一条轨道上知道我的答案。根据我自己的经验,我在 Swift 和 Objective 中使用下面的钥匙串包装器 - C. 快乐和懒惰的编码! :)

Swift - 锁匠 - https://github.com/matthewpalmer/Locksmith

Objective-C - SSKeychain - https://github.com/samsoffes/sskeychain

  //Generate Device UUID
            func CreateApplicationDeviceUUID() -> String{

                let DeviceUUID = NSUUID().uuidString
                print("DeviceUUD==\(DeviceUUID)")
                return DeviceUUID
            }



        //Retrive Device Unique UUID
                let keyChainID = Locksmith.loadDataForUserAccount(userAccount: Bundle.main.object(forInfoDictionaryKey:"CFBundleName") as! String)

                let retriveuuid = keyChainID?[RDGlobalFunction.deviceAppUUID] //RDGlobalFunction.deviceAppUUID is a Key of KeyChain Value Storage

                if(retriveuuid == nil){

                    let uuid = CreateApplicationDeviceUUID()

                    do{
                        try Locksmith.saveData(data: [RDGlobalFunction.deviceAppUUID : uuid], forUserAccount: Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String) //Locksmith - SSkeyChain Thirdparty KeyChain Wrapper
                    }catch{
                        //Catch Error 
                    }

                }

其他参考Link:

  1. https://www.raywenderlich.com/179924/secure-ios-user-data-keychain-biometrics-face-id-touch-id

  2. https://medium.com/ios-os-x-development/securing-user-data-with-keychain-for-ios-e720e0f9a8e2

  3. https://code.tutsplus.com/tutorials/securing-ios-data-at-rest--cms-28528

我发现如果我改变

let password = "testPassword"

let password = "testPassword".data(using: String.Encoding.utf8)!

然后它将按预期工作。看来kSecValueData参数必须是utf8编码的字符串。