0

I am following the Apple documentation for adding a password to the keychain located here -> https://developer.apple.com/documentation/security/keychain_services/keychain_items/adding_a_password_to_the_keychain

When I run the following code it works as expected and the status comes back as 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)

When I modify the code with hardcoded strings it fails with a status of -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)")

Can someone explain this to me? I also tried explicitly setting the strings to utf8 format with let account = "testUsername".utf8. It doesn't make sense to me that this would fail if the value is a valid string.

Also does anyone have the link to the status code descriptions? I found the descriptions but it doesn't give the associated number code https://developer.apple.com/documentation/security/1542001-security_framework_result_codes

kayzej1141
  • 55
  • 1
  • 9

2 Answers2

0

YES, I know my answer on the other track. As per my own experience, I'm using below keychain wrapper in Swift and Objective - C. Happy and Lazy Coding! :)

Swift - Locksmith - 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 
                    }

                }

Other Reference 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

Renish Dadhaniya
  • 10,642
  • 2
  • 31
  • 56
  • Hi Renish, thank you for your response. I actually did follow that very same medium post and was using this wrapper https://cocoapods.org/pods/SwiftKeychainWrapper which seemed to work. I ran into issues when I tried to use the Swift code located here https://stackoverflow.com/questions/10966969/enumerate-all-keychain-items-in-my-ios-application to enumerate my keychain items. This did not work. When I loaded data to the keychain using the struct method provided by Apple, then the enumeration worked. So I am a bit confused... – kayzej1141 Aug 02 '18 at 18:27
0

I figured out that if I change

let password = "testPassword"

to

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

then it will work as expected. It seems that the kSecValueData parameter must be a utf8 encoded string.

kayzej1141
  • 55
  • 1
  • 9