我正在尝试使用 iOS 钥匙串(keychain)测试加密。
Domain=com.apple.LocalAuthentication Code=-1009 "ACL operation is not allowed: 'od'" UserInfo={NSLocalizedDescription=ACL operation is not allowed: 'od'}
这是我的测试代码:
func testEncrpytKeychain() {
let promise = expectation(description: "Unlock")
let data: Data! = self.sampleData
let text: String! = self.sampleText
wait(for: [promise], timeout: 30)
let chain = Keychain(account: "tester", serviceName: "testing2", access: .whenPasscodeSetThisDeviceOnly, accessGroup: nil)
chain.unlockChain { reply, error in
defer {
promise.fulfill()
}
guard error == nil else {
// ** FAILS ON THIS LINE WITH OSSTATUS ERROR **
XCTAssert(false, "Error: \(String(describing: error))")
return
}
guard let cipherData = try? chain.encrypt(data) else {
XCTAssert(false, "Cipher Data not created")
return
}
XCTAssertNotEqual(cipherData, data)
guard let clearData = try? chain.decrypt(cipherData) else {
XCTAssert(false, "Clear Data not decrypted")
return
}
XCTAssertEqual(clearData, data)
let clearText = String(data: clearData, encoding: .utf8)
XCTAssertEqual(clearText, text)
}
}
这是底层异步
unlockChain
代码:// context is a LAContext
func unlockChain(_ callback: @escaping (Bool, Error?) -> Void) {
var error: NSError? = nil
guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
callback(false, error)
return
}
context.evaluateAccessControl(control, operation: .createItem, localizedReason: "Access your Account") { (reply, error) in
self.context.evaluateAccessControl(self.control, operation: .useItem, localizedReason: "Access your Account") { (reply, error) in
self.unlocked = reply
callback(reply, error)
}
}
}
以下是上下文和控制对象的制作方式
init(account: String, serviceName: String = (Bundle.main.bundleIdentifier ?? ""), access: Accessibility = .whenUnlocked, accessGroup: String? = nil) {
self.account = account
self.serviceName = serviceName
self.accessGroup = accessGroup
self.access = access
var error: Unmanaged<CFError>? = nil
self.control = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
access.attrValue,
[.privateKeyUsage],
&error)
if let e: Error = error?.takeRetainedValue() {
Log.error(e)
}
self.context = LAContext()
}
我找不到有关此错误的任何信息:
Domain=com.apple.LocalAuthentication Code=-1009
OSStatus Code site doesn't contain anything for it either
任何帮助表示赞赏,谢谢。
最佳答案
我通过在创建新私钥之前删除以前的私钥解决了同样的问题。
我猜想在 iOS10 上(11 没有显示错误),当你 SecKeyCreateRandomKey(...)
具有相同的标签/大小但不同的访问设置,它只会返回 true
但使用旧的(感觉很奇怪,但谁知道)?
这是我刚刚删除的一个惰性 C 函数(只要记住设置你的 ApplicationPrivateKeyTag
:
void deletePrivateKey()
{
CFStringRef ApplicationPrivateKeyTag = CFSTR("your tag here");
const void* keys[] = {
kSecAttrApplicationTag,
kSecClass,
kSecAttrKeyClass,
kSecReturnRef,
};
const void* values[] = {
ApplicationPrivateKeyTag,
kSecClassKey,
kSecAttrKeyClassPrivate,
kCFBooleanTrue,
};
CFDictionaryRef params = CFDictionaryCreate(kCFAllocatorDefault, keys, values, (sizeof(keys)/sizeof(void*)), NULL, NULL);
OSStatus status = SecItemDelete(params);
if (params) CFRelease(params);
if (ApplicationPrivateKeyTag) CFRelease(ApplicationPrivateKeyTag);
if (status == errSecSuccess)
return true;
return false;
}
FWIW:看起来苹果更新了their doc about the Security Framework and the SecureEnclave ,现在更容易理解了。
关于xcode - OSStatus 代码 -1009,com.apple.LocalAuthentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43806557/