【问题标题】:OSStatus Code -1009, com.apple.LocalAuthenticationOSStatus 代码 -1009,com.apple.LocalAuthentication
【发布时间】:2017-10-04 00:44:09
【问题描述】:

我正在尝试使用 iOS 钥匙串测试加密。

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

感谢任何帮助,谢谢。

【问题讨论】:

  • 这看起来像是在单元测试中运行它。它在设备上也会失败吗?如果它不在物理设备上运行,它只是感觉有点不稳定。
  • 它正在设备上的单元测试中运行。另外,我在设备上应用内运行过,报错信息也是一样的。
  • 我在尝试使用“ecdsa 摘要”算法签名时遇到了同样的错误。你找到它的来源了吗? Error Domain=com.apple.LocalAuthentication Code=-1009 "ACL operation is not allowed: 'osgn'" UserInfo={NSLocalizedDescription=ACL operation is not allowed: 'osgn' 我这边没有测试,最奇怪的是它在 iOS11 上运行良好,但在 iOS10 上却不行 :(

标签: xcode keychain xctest osstatus


【解决方案1】:

我通过在创建新私钥之前删除以前的私钥解决了同样的问题。

我猜在 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,现在更容易理解了。

【讨论】:

    猜你喜欢
    • 2014-01-16
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2014-08-25
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多