Keychain 中同一个 kSecAttrAccount 的两个不同值
Two different values from the same kSecAttrAccount in Keychain
对此我真的很纳闷
我有一个 class 初始化如下:
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([=11=]))
}
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 returns:
[..., "Nonimportant": "correct value", "Important": "correct value", ...]
MyClass 初始化程序中的 print(value) 行打印:
V1: "correct value"
V2: "incorrect value"
这两个调用怎么可能几乎一个接一个 return V2 钥匙串中同一位置的两个不同值,同时 V1 没问题?
谢谢
好的,我找到问题了。
确实有两个不同的数据值。
这个 class 是更新后执行此操作的框架的一部分。因此,以前版本的框架使用另一个框架来管理钥匙串,并且该框架存储的数据具有比我的新版本更多的属性。我认为替换数据实际上是添加属性较少的新条目。
所以在 运行 遗留代码之后的最后,然后用新版本更新它,在“相同”键处有两个数据条目。
对此我真的很纳闷
我有一个 class 初始化如下:
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([=11=]))
}
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 returns:
[..., "Nonimportant": "correct value", "Important": "correct value", ...]
MyClass 初始化程序中的 print(value) 行打印:
V1: "correct value"
V2: "incorrect value"
这两个调用怎么可能几乎一个接一个 return V2 钥匙串中同一位置的两个不同值,同时 V1 没问题?
谢谢
好的,我找到问题了。 确实有两个不同的数据值。
这个 class 是更新后执行此操作的框架的一部分。因此,以前版本的框架使用另一个框架来管理钥匙串,并且该框架存储的数据具有比我的新版本更多的属性。我认为替换数据实际上是添加属性较少的新条目。
所以在 运行 遗留代码之后的最后,然后用新版本更新它,在“相同”键处有两个数据条目。