来自钥匙串中相同kSecAttrAccount的两个不同值

问题描述

我真的对此感到困惑。

我有一个这样初始化的类:

class MyClass {
  let storage = Storage.sharedService

  static let sharedInstance = MyClass()
  fileprivate init() {
    storage.dumpKeychain()
    v1 = storage.loadNonimportantValue()
    print("V1: \(v1 ?? "nil")")
    v2 = storage.loadImportantValue()
    print("V2: \(v2 ?? "nil")")
  }
}

storage.dumpKeychain()是函数(从互联网获取),可打印我的应用可访问的钥匙串的内容

func dumpKeychain() {
  let query: [String: Any] = [
    kSecclass as String : kSecclassGenericPassword,kSecReturnData as String  : kcfBooleanFalse!,kSecReturnAttributes as String : kcfBooleanTrue!,kSecReturnRef as String : kcfBooleanTrue!,kSecMatchLimit as String: kSecMatchLimitAll
  ]

  var result: AnyObject?

  let lastResultCode = withUnsafeMutablePointer(to: &result) {
    SecItemcopyMatching(query as CFDictionary,UnsafeMutablePointer($0))
  }

  var values = [String:String]()
  if lastResultCode == noErr {
    let array = result as? Array<Dictionary<String,Any>>
    for item in array! {
      if let key = item[kSecAttrAccount as String] as? String,let value = item[kSecValueData as String] as? Data {
        values[key] = String(data: value,encoding:.utf8)
      }
    }
  }
  print(values)
}

storage.loadImportantValue()是从给定的kSecAttrAccount(“重要”)加载值的函数

fileprivate func loadImportantValue() -> String? {

  var readQuery : [String : Any] = [
    kSecclass as String: kSecclassGenericPassword,kSecAttrAccount as String: "Important",kSecReturnData as String: kcfBooleanTrue!
  ]

  var storedData : AnyObject?
  _ = SecItemcopyMatching(readQuery as CFDictionary,&storedData);

  return String(data: storedData as? Data,encoding: String.Encoding.utf8)
}

我在日志中看到的是dumpKeychain返回:

[...,"Nonimportant": "correct value","Important": "correct value",...]

然后MyClass初始化程序中的行print(value)打印:

V1: "correct value"
V2: "incorrect value"

这两个调用几乎不可能接连发生,从V2的钥匙串中的同一位置返回两个不同的值,同时V1正常吗?

谢谢

解决方法

好的,我发现了问题。 数据确实有两个不同的值。

此类是框架的一部分,该框架在更新后正在执行此操作。因此,该框架的先前版本正在使用另一个框架来管理钥匙串,并且该框架存储的数据具有比我的新版本更多的属性。而且我认为替换数据实际上是在添加具有较少属性的新条目。

因此,最后,在运行旧版代码并使用较新版本进行更新之后,“相同”键上有两个数据条目。