#ios #swift #keychain
#iOS #swift #связка ключей
Вопрос:
У меня есть функция, которая создает новый ключ в связке ключей iOS, используя этот метод:
func initialize(_ keyTag: String) throws -> DeviceBindingParameters {
let tag = keyTag.data(using: .utf8)!
let attributes: [String: Any] =
[kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 256,
kSecPrivateKeyAttrs as String: [
kSecAttrIsPermanent as String: true,
kSecAttrLabel as String: tag,
kSecAttrApplicationTag as String: tag
]
]
... other stuff
}
И затем есть также функция, которая проверяет, присутствует ли этот ключ или нет:
open func doesKeyExist(_ keyTag: String) -> Bool {
let tag = keyTag.data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String : kSecAttrKeyType,
kSecAttrLabel as String : tag,
kSecAttrApplicationTag as String: tag,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecReturnRef as String: true
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, amp;item)
let errorDescription = SecCopyErrorMessageString(status,nil)
print(errorDescription)
return status == noErr
}
И я вызываю этот метод просто один за другим (для быстрого тестирования я вызываю это из AppDelegate.swift
:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try crypto.initialize("rohan-key")
let keyStatus = try crypto.doesKeyExist("rohan-key")
print("Key status: (keyStatus)")
} catch {
print("errors")
}
И я всегда получаю этот вывод:
Optional(The specified item does not appear to be a valid keychain item.)
Key status: false
Первое сообщение печатается при вызове состояния SecCopyErrorMessageString
on SecItemCopyMatching
. Кроме того, я очень уверен, что генерация ключа работает, потому что я использую ключ для подписи канонического сообщения, отправки его по проводам, а затем проверки этой подписи на серверной части на основе Java — так что эти части полностью в порядке. Я просто не уверен, почему элемент не сохраняется в хранилище ключей.
Ответ №1:
Вы допустили незначительную ошибку в kSecClass as String : kSecAttrKeyType
. kSecAttrKeyType
является ключом, указывающим тип ключа ( kSecAttrKeyTypeEC
/ kSecAttrKeyTypeECSECPrimeRandom
/ kSecAttrKeyTypeRSA
). Поэтому вы должны передать правильное kSecClass
, которое для вас должно быть kSecClassKey
.
Я хотел бы отметить, что время от времени вывод SecCopyErrorMessageString
немного плохой. Всегда пытайтесь OSStatus
также распечатать и использовать это в OSStatus. Что в этом случае не дало бы вам наибольших результатов, так как вернуло бы -50. Но комбинация этих двух идентифицирует их достаточно однозначно, чтобы определить ее так, как errSecNoSuchClass
найдено здесь .
Комментарии:
1. Да. Похоже, что это так, и спасибо за ссылку на osstatus — это очень полезно!