SecItemCopyMatching 始终 returns 'does not appear to be a valid keychain item' 用于存储的 EC 密钥
SecItemCopyMatching always returns 'does not appear to be a valid keychain item' for a stored EC key
我有一个函数可以使用此方法在 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, &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
第一条消息是在 SecItemCopyMatching
的状态下调用 SecCopyErrorMessageString
打印的。此外,我非常确定密钥生成工作正常,因为我使用密钥签署规范消息,通过网络发送它,然后在基于 Java 的后端验证该签名 - 所以这些部分完全没问题.我只是不确定为什么该项目没有保留在密钥库中。
您在 kSecClass as String : kSecAttrKeyType
处犯了一个小错误。 kSecAttrKeyType
是表示key类型的key(kSecAttrKeyTypeEC
/kSecAttrKeyTypeECSECPrimeRandom
/kSecAttrKeyTypeRSA
)。所以你应该传递正确的 kSecClass
对你来说应该是 kSecClassKey
.
我想指出 SecCopyErrorMessageString
的输出时不时有点糟糕。始终尝试打印 OSStatus
并在 OSStatus. Which in this case would not have given you greatest hits, as it would've returned -50. But the combination of the two identifies them uniquely enough to define it as errSecNoSuchClass
found here.
上使用它
我有一个函数可以使用此方法在 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, &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
第一条消息是在 SecItemCopyMatching
的状态下调用 SecCopyErrorMessageString
打印的。此外,我非常确定密钥生成工作正常,因为我使用密钥签署规范消息,通过网络发送它,然后在基于 Java 的后端验证该签名 - 所以这些部分完全没问题.我只是不确定为什么该项目没有保留在密钥库中。
您在 kSecClass as String : kSecAttrKeyType
处犯了一个小错误。 kSecAttrKeyType
是表示key类型的key(kSecAttrKeyTypeEC
/kSecAttrKeyTypeECSECPrimeRandom
/kSecAttrKeyTypeRSA
)。所以你应该传递正确的 kSecClass
对你来说应该是 kSecClassKey
.
我想指出 SecCopyErrorMessageString
的输出时不时有点糟糕。始终尝试打印 OSStatus
并在 OSStatus. Which in this case would not have given you greatest hits, as it would've returned -50. But the combination of the two identifies them uniquely enough to define it as errSecNoSuchClass
found here.