钥匙串 API 只查看系统钥匙串,不查看登录钥匙串 Mac OS Swift
Keychain API is looking only into system keychain not in login keychain Mac OS Swift
我在钥匙串方面需要一些帮助 API。我正在 mac os 应用程序中使用钥匙串 API 在钥匙串中搜索证书。但是,它只在 system.keychain 中搜索,而不是在 login.keychain 中搜索。我没有找到任何可以在钥匙串搜索查询中放置或指定钥匙串的文档。当前代码如下。
func isKeychainhasCert(for sNumber:Data) -> Bool {
var query = [String: AnyObject]()
query[kSecClass as String] = kSecClassCertificate
query[kSecAttrSerialNumber as String] = sNumber as CFData
query[kSecReturnRef as String] = true as CFBoolean
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult, {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer([=14=]))
})
guard status != errSecItemNotFound else {
return false
}
return true
}
任何帮助或建议。基于以上代码,方法 return 仅当存在证书 system.keychain 时才为真。如果存在于 login.keychain 但不存在于 system.keychain return false.
这不是答案,但可能会阐明如何获得证书:
import Foundation
import Security
var result: OSStatus
// Usually, we operate in the "user" domain, check this:
var domain: SecPreferencesDomain = .system
result = SecKeychainGetPreferenceDomain(&domain)
if result == errSecSuccess {
assert(domain == .user)
}
// Get the list of searched keychains of the current domain:
// (it should include the "default" keychain for the "user" domain)
var searchList: CFArray? = nil
result = SecKeychainCopyDomainSearchList(domain, &searchList)
guard result == errSecSuccess, let searchedKeyChains = searchList as? [SecKeychain] else {
fatalError("SecKeychainCopyDomainSearchList failed")
}
print("Keychain search list:")
searchedKeyChains.forEach { keyChain in
print(keyChain)
}
print("")
// Get the default keychain for the current domain:
var defaultKeyChain: SecKeychain? = nil
result = SecKeychainCopyDefault(&defaultKeyChain)
guard result == errSecSuccess, defaultKeyChain != nil else {
fatalError("SecKeychainCopyDefault failed")
}
print("Default Keychain: \(defaultKeyChain!)")
到目前为止,我们只做了一些检查和测试。
现在,搜索钥匙串中的所有证书:
// Here, search all "searchable" keychains, by not specifying a
// kSecMatchSearchList value.
var copyResult: CFTypeRef? = nil
result = SecItemCopyMatching([
kSecClass: kSecClassCertificate,
kSecMatchLimit: kSecMatchLimitAll,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard result == errSecSuccess, let certificates1 = copyResult as? [SecCertificate] else {
fatalError("unexpected result type: \(copyResult)")
}
打印所有找到的证书:
certificates1.forEach { cert in
print(cert)
}
仅在当前域的“默认”钥匙串中搜索(应为 .user
)。我们通过指定 kSecMatchSearchList
参数来做到这一点:
// Here, search only the default keychain:
result = SecItemCopyMatching([
kSecClass: kSecClassCertificate,
kSecMatchLimit: kSecMatchLimitAll,
kSecMatchSearchList: [defaultKeyChain] as CFArray,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard result == errSecSuccess, let certificates2 = copyResult as? [SecCertificate] else {
fatalError("unexpected result type: \(copyResult)")
}
现在,让我们看看在默认钥匙串之外的任何其他钥匙串中发现了哪些额外的证书:
let diff = Array(Set(certificates1).symmetricDifference(Set(certificates2)))
print("Difference:")
diff.forEach { cert in
print(cert)
}
print("")
我在钥匙串方面需要一些帮助 API。我正在 mac os 应用程序中使用钥匙串 API 在钥匙串中搜索证书。但是,它只在 system.keychain 中搜索,而不是在 login.keychain 中搜索。我没有找到任何可以在钥匙串搜索查询中放置或指定钥匙串的文档。当前代码如下。
func isKeychainhasCert(for sNumber:Data) -> Bool {
var query = [String: AnyObject]()
query[kSecClass as String] = kSecClassCertificate
query[kSecAttrSerialNumber as String] = sNumber as CFData
query[kSecReturnRef as String] = true as CFBoolean
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult, {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer([=14=]))
})
guard status != errSecItemNotFound else {
return false
}
return true
}
任何帮助或建议。基于以上代码,方法 return 仅当存在证书 system.keychain 时才为真。如果存在于 login.keychain 但不存在于 system.keychain return false.
这不是答案,但可能会阐明如何获得证书:
import Foundation
import Security
var result: OSStatus
// Usually, we operate in the "user" domain, check this:
var domain: SecPreferencesDomain = .system
result = SecKeychainGetPreferenceDomain(&domain)
if result == errSecSuccess {
assert(domain == .user)
}
// Get the list of searched keychains of the current domain:
// (it should include the "default" keychain for the "user" domain)
var searchList: CFArray? = nil
result = SecKeychainCopyDomainSearchList(domain, &searchList)
guard result == errSecSuccess, let searchedKeyChains = searchList as? [SecKeychain] else {
fatalError("SecKeychainCopyDomainSearchList failed")
}
print("Keychain search list:")
searchedKeyChains.forEach { keyChain in
print(keyChain)
}
print("")
// Get the default keychain for the current domain:
var defaultKeyChain: SecKeychain? = nil
result = SecKeychainCopyDefault(&defaultKeyChain)
guard result == errSecSuccess, defaultKeyChain != nil else {
fatalError("SecKeychainCopyDefault failed")
}
print("Default Keychain: \(defaultKeyChain!)")
到目前为止,我们只做了一些检查和测试。
现在,搜索钥匙串中的所有证书:
// Here, search all "searchable" keychains, by not specifying a
// kSecMatchSearchList value.
var copyResult: CFTypeRef? = nil
result = SecItemCopyMatching([
kSecClass: kSecClassCertificate,
kSecMatchLimit: kSecMatchLimitAll,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard result == errSecSuccess, let certificates1 = copyResult as? [SecCertificate] else {
fatalError("unexpected result type: \(copyResult)")
}
打印所有找到的证书:
certificates1.forEach { cert in
print(cert)
}
仅在当前域的“默认”钥匙串中搜索(应为 .user
)。我们通过指定 kSecMatchSearchList
参数来做到这一点:
// Here, search only the default keychain:
result = SecItemCopyMatching([
kSecClass: kSecClassCertificate,
kSecMatchLimit: kSecMatchLimitAll,
kSecMatchSearchList: [defaultKeyChain] as CFArray,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard result == errSecSuccess, let certificates2 = copyResult as? [SecCertificate] else {
fatalError("unexpected result type: \(copyResult)")
}
现在,让我们看看在默认钥匙串之外的任何其他钥匙串中发现了哪些额外的证书:
let diff = Array(Set(certificates1).symmetricDifference(Set(certificates2)))
print("Difference:")
diff.forEach { cert in
print(cert)
}
print("")