Создание пары ключей в iOS с помощью SecKeyGeneratePair не удалось с ошибкой errSecInteractionNotAllowed

В моем приложении я использую SecKeyGeneratePair для создания пары ключей RSA. После выпуска приложения я начал замечать случайные errSecInteractionNotAllowed ошибки (в настоящее время очень редкие) при использовании этой функции, пока только на устройствах iOS 10. Мне непонятно, почему произошла ошибка генерации пары ключей или что я должен сделать, чтобы это исправить. Кроме того, я не смог найти никакой документации о том, почему генерация пары ключей должна завершаться сбоем с этой ошибкой.

Это код, который я использовал для создания пары ключей:

guard let access = SecAccessControlCreateWithFlags(nil,
                                                       kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
                                                       [],
                                                       nil) else {throw Error(description: "Failed to create access control")}

    let privateAttributes = [String(kSecAttrIsPermanent): true,
                             String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
                             String(kSecAttrAccessControl): access] as [String : Any]
    let publicAttributes = [String(kSecAttrIsPermanent): true,
                            String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension] as [String : Any]

    let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
                          String(kSecAttrKeySizeInBits): self.rsaKeySize,
                          String(kSecPublicKeyAttrs): publicAttributes,
                          String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
    var pubKey, privKey: SecKey?
    let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)

После этого кода я проверяю статус, и если он не errSecSuccess, я регистрирую ошибку со статусом, возвращенным функцией. Здесь я заметил ошибку errSecInteractionNotAllowed. Итак, почему происходит генерация пары ключей или что я могу сделать, чтобы это исправить?

Спасибо,

Омер


person Omer Levi Hevroni    schedule 21.12.2016    source источник


Ответы (2)


Два предложения:

  1. Попробуйте добавить другой класс защиты, например kSecAttrAccessibleAlways, в вызов SecAccessControlCreateWithFlags и протестируйте если поведение по-прежнему возникает.
  2. Далее определите флаг для вашего варианта использования вместо передачи пустого массива. Например. userPresence.

Кроме того, я наткнулся на этот сообщение SO, возможно, вы сможете найти немного вдохновения.

person David Artmann    schedule 27.11.2017
comment
Спасибо! Собственно, это было решено разговорами с техподдержкой Apple. Проблема заключалась в неправильном использовании флага - его нужно передавать как один из ключевых параметров (в массиве). - person Omer Levi Hevroni; 27.11.2017
comment
Привет, Омер, без проблем. Я столкнулся с этим, исследуя криптографический API iOS. Один вопрос: вы имеете в виду флаг kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly? Если есть какая-то ветка форума, в которой вы обсуждали и решали проблему, то свяжите ее здесь. Может быть, это поможет другим в будущем;) - person David Artmann; 27.11.2017
comment
Нет, извините - использовалась служба технической поддержки Apple, а не что-то публичное. Я сейчас отвечу на вопрос и отмечу его как ответ. - person Omer Levi Hevroni; 28.11.2017
comment
Отлично, спасибо. Но вы должны признаться, я был довольно близок к вашему решению с моим предыдущим ответом;) - person David Artmann; 28.11.2017

После обсуждения этого вопроса со службой поддержки разработчиков Apple, вот решение:

 let privateAttributes = [String(kSecAttrIsPermanent): true,
                                 String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
                                 String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]
        let publicAttributes = [String(kSecAttrIsPermanent): true,
                                String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension,
                                String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]

        let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
                              String(kSecAttrKeySizeInBits): self.rsaKeySize,
                              String(kSecPublicKeyAttrs): publicAttributes,
                              String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
        var pubKey, privKey: SecKey?
        let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)

Важной частью является kSecAttrAccessible, выберите значение, соответствующее вашим потребностям, из этого список. Обратите внимание, что некоторые значения ограничивают доступ к ключу в KeyVault.

person Omer Levi Hevroni    schedule 28.11.2017