cryptotokenkit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCryptoTokenKit
CryptoTokenKit
Access security tokens and the cryptographic assets they store using the
CryptoTokenKit framework. Covers token driver extensions, smart card
communication, token sessions, keychain integration, and certificate-based
authentication. Targets Swift 6.3.
Platform availability: CryptoTokenKit is primarily a macOS framework.
Smart card reader access (, ) requires
macOS. Token extension APIs (, , )
are macOS-only. Client-side token watching () and keychain
queries filtered by are available on iOS 14+/macOS 11+.
NFC smart card slot sessions are available on iOS 16.4+.
TKSmartCardTKSmartCardSlotManagerTKTokenDriverTKTokenTKTokenSessionTKTokenWatcherkSecAttrTokenID使用CryptoTokenKit框架访问安全令牌及其存储的加密资产。内容涵盖令牌驱动扩展、智能卡通信、令牌会话、钥匙串集成以及基于证书的身份验证。适配Swift 6.3版本。
平台可用性: CryptoTokenKit主要是一款macOS框架。智能卡读卡器访问(, )仅支持macOS。令牌扩展API(, , )仅适用于macOS。客户端令牌监控()和通过过滤的钥匙串查询支持iOS 14+/macOS 11+。NFC智能卡插槽会话支持iOS 16.4+。
TKSmartCardTKSmartCardSlotManagerTKTokenDriverTKTokenTKTokenSessionTKTokenWatcherkSecAttrTokenIDContents
目录
Architecture Overview
架构概述
CryptoTokenKit bridges hardware security tokens (smart cards, USB tokens)
with macOS authentication and keychain services. The framework has two main
usage modes:
Token driver extensions (macOS only) -- App extensions that make a
hardware token's cryptographic items available to the system. The driver
handles token lifecycle, session management, and cryptographic operations.
Client-side token access (macOS + iOS) -- Apps query the keychain for
items backed by tokens. CryptoTokenKit automatically exposes token items as
standard keychain entries when a token is present.
CryptoTokenKit将硬件安全令牌(智能卡、USB令牌)与macOS身份验证和钥匙串服务相连接。该框架有两种主要使用模式:
令牌驱动扩展(仅macOS)—— 使硬件令牌的加密项对系统可用的应用扩展。宿主应用仅作为扩展的交付载体。
客户端令牌访问(macOS + iOS)—— 应用查询钥匙串中由令牌支持的项。当令牌存在时,CryptoTokenKit会自动将令牌项暴露为标准钥匙串条目。
Key Types
核心类型
| Type | Role | Platform |
|---|---|---|
| Base class for token driver extensions | macOS |
| Represents a hardware cryptographic token | macOS |
| Manages authentication state for a token | macOS |
| Entry point for smart card extensions | macOS |
| Low-level smart card communication | macOS |
| Discovers and manages card reader slots | macOS |
| Observes token insertion and removal | macOS, iOS 14+ |
| A key stored on a token | macOS |
| A certificate stored on a token | macOS |
| 类型 | 作用 | 平台 |
|---|---|---|
| 令牌驱动扩展的基类 | macOS |
| 表示硬件加密令牌 | macOS |
| 管理令牌的身份验证状态 | macOS |
| 智能卡扩展的入口点 | macOS |
| 底层智能卡通信 | macOS |
| 发现并管理读卡器插槽 | macOS |
| 监控令牌的插入和移除 | macOS, iOS 14+ |
| 存储在令牌上的密钥 | macOS |
| 存储在令牌上的证书 | macOS |
Token Extensions
令牌扩展
A token driver is a macOS app extension that makes a hardware token's
cryptographic capabilities available to the system. The host app exists
only as a delivery mechanism for the extension.
A smart card token extension has three core classes:
- TokenDriver (subclass of ) -- entry point
TKSmartCardTokenDriver - Token (subclass of ) -- represents the token
TKSmartCardToken - TokenSession (subclass of ) -- handles operations
TKSmartCardTokenSession
令牌驱动是一款macOS应用扩展,用于使硬件令牌的加密功能对系统可用。宿主应用仅作为扩展的交付载体。
智能卡令牌扩展包含三个核心类:
- TokenDriver(的子类)—— 入口点
TKSmartCardTokenDriver - Token(的子类)—— 表示令牌
TKSmartCardToken - TokenSession(的子类)—— 处理操作
TKSmartCardTokenSession
Driver Class
驱动类
swift
import CryptoTokenKit
final class TokenDriver: TKSmartCardTokenDriver, TKSmartCardTokenDriverDelegate {
func tokenDriver(
_ driver: TKSmartCardTokenDriver,
createTokenFor smartCard: TKSmartCard,
aid: Data?
) throws -> TKSmartCardToken {
return try Token(
smartCard: smartCard,
aid: aid,
instanceID: "com.example.token:\(smartCard.slot.name)",
tokenDriver: driver
)
}
}swift
import CryptoTokenKit
final class TokenDriver: TKSmartCardTokenDriver, TKSmartCardTokenDriverDelegate {
func tokenDriver(
_ driver: TKSmartCardTokenDriver,
createTokenFor smartCard: TKSmartCard,
aid: Data?
) throws -> TKSmartCardToken {
return try Token(
smartCard: smartCard,
aid: aid,
instanceID: "com.example.token:\(smartCard.slot.name)",
tokenDriver: driver
)
}
}Token Class
令牌类
The token reads certificates and keys from hardware and populates its
keychain contents:
swift
final class Token: TKSmartCardToken, TKTokenDelegate {
init(
smartCard: TKSmartCard, aid: Data?,
instanceID: String, tokenDriver: TKSmartCardTokenDriver
) throws {
try super.init(
smartCard: smartCard, aid: aid,
instanceID: instanceID, tokenDriver: tokenDriver
)
self.delegate = self
let certData = try readCertificate(from: smartCard)
guard let cert = SecCertificateCreateWithData(nil, certData as CFData) else {
throw TKError(.corruptedData)
}
let certItem = TKTokenKeychainCertificate(certificate: cert, objectID: "cert-auth")
let keyItem = TKTokenKeychainKey(certificate: cert, objectID: "key-auth")
keyItem?.canSign = true
keyItem?.canDecrypt = false
keyItem?.isSuitableForLogin = true
self.keychainContents?.fill(with: [certItem!, keyItem!])
}
func createSession(_ token: TKToken) throws -> TKTokenSession {
TokenSession(token: token)
}
}令牌从硬件读取证书和密钥,并填充其钥匙串内容:
swift
final class Token: TKSmartCardToken, TKTokenDelegate {
init(
smartCard: TKSmartCard, aid: Data?,
instanceID: String, tokenDriver: TKSmartCardTokenDriver
) throws {
try super.init(
smartCard: smartCard, aid: aid,
instanceID: instanceID, tokenDriver: tokenDriver
)
self.delegate = self
let certData = try readCertificate(from: smartCard)
guard let cert = SecCertificateCreateWithData(nil, certData as CFData) else {
throw TKError(.corruptedData)
}
let certItem = TKTokenKeychainCertificate(certificate: cert, objectID: "cert-auth")
let keyItem = TKTokenKeychainKey(certificate: cert, objectID: "key-auth")
keyItem?.canSign = true
keyItem?.canDecrypt = false
keyItem?.isSuitableForLogin = true
self.keychainContents?.fill(with: [certItem!, keyItem!])
}
func createSession(_ token: TKToken) throws -> TKTokenSession {
TokenSession(token: token)
}
}Info.plist and Registration
Info.plist与注册
The extension's must name the driver class:
Info.plistNSExtension
NSExtensionAttributes
com.apple.ctk.driver-class = $(PRODUCT_MODULE_NAME).TokenDriver
NSExtensionPointIdentifier = com.apple.ctk-tokensRegister the extension once by launching the host app as :
_securityagentshell
sudo -u _securityagent /Applications/TokenHost.app/Contents/MacOS/TokenHost扩展的必须指定驱动类:
Info.plistNSExtension
NSExtensionAttributes
com.apple.ctk.driver-class = $(PRODUCT_MODULE_NAME).TokenDriver
NSExtensionPointIdentifier = com.apple.ctk-tokens通过以身份启动宿主应用,完成一次扩展注册:
_securityagentshell
sudo -u _securityagent /Applications/TokenHost.app/Contents/MacOS/TokenHostToken Sessions
令牌会话
TKTokenSessionswift
final class TokenSession: TKSmartCardTokenSession, TKTokenSessionDelegate {
func tokenSession(
_ session: TKTokenSession,
supports operation: TKTokenOperation,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) -> Bool {
switch operation {
case .signData:
return algorithm.isAlgorithm(.rsaSignatureDigestPKCS1v15SHA256)
|| algorithm.isAlgorithm(.ecdsaSignatureDigestX962SHA256)
case .decryptData:
return algorithm.isAlgorithm(.rsaEncryptionOAEPSHA256)
case .performKeyExchange:
return algorithm.isAlgorithm(.ecdhKeyExchangeStandard)
default:
return false
}
}
func tokenSession(
_ session: TKTokenSession,
sign dataToSign: Data,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) throws -> Data {
let smartCard = try getSmartCard()
return try smartCard.withSession {
try performCardSign(smartCard: smartCard, data: dataToSign, keyID: keyObjectID)
}
}
func tokenSession(
_ session: TKTokenSession,
decrypt ciphertext: Data,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) throws -> Data {
let smartCard = try getSmartCard()
return try smartCard.withSession {
try performCardDecrypt(smartCard: smartCard, data: ciphertext, keyID: keyObjectID)
}
}
}TKTokenSessionswift
final class TokenSession: TKSmartCardTokenSession, TKTokenSessionDelegate {
func tokenSession(
_ session: TKTokenSession,
supports operation: TKTokenOperation,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) -> Bool {
switch operation {
case .signData:
return algorithm.isAlgorithm(.rsaSignatureDigestPKCS1v15SHA256)
|| algorithm.isAlgorithm(.ecdsaSignatureDigestX962SHA256)
case .decryptData:
return algorithm.isAlgorithm(.rsaEncryptionOAEPSHA256)
case .performKeyExchange:
return algorithm.isAlgorithm(.ecdhKeyExchangeStandard)
default:
return false
}
}
func tokenSession(
_ session: TKTokenSession,
sign dataToSign: Data,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) throws -> Data {
let smartCard = try getSmartCard()
return try smartCard.withSession {
try performCardSign(smartCard: smartCard, data: dataToSign, keyID: keyObjectID)
}
}
func tokenSession(
_ session: TKTokenSession,
decrypt ciphertext: Data,
keyObjectID: TKToken.ObjectID,
algorithm: TKTokenKeyAlgorithm
) throws -> Data {
let smartCard = try getSmartCard()
return try smartCard.withSession {
try performCardDecrypt(smartCard: smartCard, data: ciphertext, keyID: keyObjectID)
}
}
}PIN Authentication
PIN身份验证
Return a from to prompt the user
for PIN entry before cryptographic operations:
TKTokenAuthOperationbeginAuthFor:swift
func tokenSession(
_ session: TKTokenSession,
beginAuthFor operation: TKTokenOperation,
constraint: Any
) throws -> TKTokenAuthOperation {
let pinAuth = TKTokenSmartCardPINAuthOperation()
pinAuth.pinFormat.charset = .numeric
pinAuth.pinFormat.minPINLength = 4
pinAuth.pinFormat.maxPINLength = 8
pinAuth.smartCard = (session as? TKSmartCardTokenSession)?.smartCard
pinAuth.apduTemplate = buildVerifyAPDU()
pinAuth.pinByteOffset = 5
return pinAuth
}从返回,以便在执行加密操作前提示用户输入PIN:
beginAuthFor:TKTokenAuthOperationswift
func tokenSession(
_ session: TKTokenSession,
beginAuthFor operation: TKTokenOperation,
constraint: Any
) throws -> TKTokenAuthOperation {
let pinAuth = TKTokenSmartCardPINAuthOperation()
pinAuth.pinFormat.charset = .numeric
pinAuth.pinFormat.minPINLength = 4
pinAuth.pinFormat.maxPINLength = 8
pinAuth.smartCard = (session as? TKSmartCardTokenSession)?.smartCard
pinAuth.apduTemplate = buildVerifyAPDU()
pinAuth.pinByteOffset = 5
return pinAuth
}Smart Card Communication
智能卡通信
TKSmartCardTKSmartCardDiscovering Card Readers
发现读卡器
swift
import CryptoTokenKit
func discoverSmartCards() {
guard let slotManager = TKSmartCardSlotManager.default else {
print("Smart card services unavailable")
return
}
for slotName in slotManager.slotNames {
slotManager.getSlot(withName: slotName) { slot in
guard let slot else { return }
if slot.state == .validCard, let card = slot.makeSmartCard() {
communicateWith(card: card)
}
}
}
}swift
import CryptoTokenKit
func discoverSmartCards() {
guard let slotManager = TKSmartCardSlotManager.default else {
print("Smart card services unavailable")
return
}
for slotName in slotManager.slotNames {
slotManager.getSlot(withName: slotName) { slot in
guard let slot else { return }
if slot.state == .validCard, let card = slot.makeSmartCard() {
communicateWith(card: card)
}
}
}
}Sending APDU Commands
发送APDU命令
Use for structured APDU communication.
Always wrap calls in :
send(ins:p1:p2:data:le:)withSessionswift
func selectApplication(card: TKSmartCard, aid: Data) throws {
try card.withSession {
let (sw, response) = try card.send(
ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil
)
guard sw == 0x9000 else {
throw TKError(.communicationError)
}
}
}For raw APDU bytes or non-standard formats, use with
manual / lifecycle management.
transmit(_:reply:)beginSessionendSession使用进行结构化APDU通信。始终将调用包裹在中:
send(ins:p1:p2:data:le:)withSessionswift
func selectApplication(card: TKSmartCard, aid: Data) throws {
try card.withSession {
let (sw, response) = try card.send(
ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil
)
guard sw == 0x9000 else {
throw TKError(.communicationError)
}
}
}对于原始APDU字节或非标准格式,使用并手动管理/生命周期。
transmit(_:reply:)beginSessionendSessionNFC Smart Card Sessions (iOS 16.4+)
NFC智能卡会话(iOS 16.4+)
On supported iOS devices, create NFC smart card sessions to communicate
with contactless smart cards:
swift
func readNFCSmartCard() {
guard let slotManager = TKSmartCardSlotManager.default,
slotManager.isNFCSupported() else { return }
slotManager.createNFCSlot(message: "Hold card near iPhone") { session, error in
guard let session else { return }
defer { session.end() }
guard let slotName = session.slotName,
let slot = slotManager.slotNamed(slotName),
let card = slot.makeSmartCard() else { return }
// Communicate with the NFC card using card.send(...)
}
}在支持的iOS设备上,创建NFC智能卡会话以与非接触式智能卡通信:
swift
func readNFCSmartCard() {
guard let slotManager = TKSmartCardSlotManager.default,
slotManager.isNFCSupported() else { return }
slotManager.createNFCSlot(message: "Hold card near iPhone") { session, error in
guard let session else { return }
defer { session.end() }
guard let slotName = session.slotName,
let slot = slotManager.slotNamed(slotName),
let card = slot.makeSmartCard() else { return }
// Communicate with the NFC card using card.send(...)
}
}Keychain Integration
钥匙串集成
When a token is present, CryptoTokenKit exposes its items as standard
keychain entries. Query them using the attribute:
kSecAttrTokenIDswift
import Security
func findTokenKey(tokenID: String) throws -> SecKey {
let query: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrTokenID as String: tokenID,
kSecReturnRef as String: true
]
var result: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status == errSecSuccess, let key = result else {
throw TKError(.objectNotFound)
}
return key as! SecKey
}Use instead of to obtain a
persistent reference that survives across app launches. The reference
becomes invalid when the token is removed -- handle
by prompting the user to reinsert the token.
kSecReturnPersistentRefkSecReturnReferrSecItemNotFoundQuery certificates the same way with .
kSecClass: kSecClassCertificate当令牌存在时,CryptoTokenKit会将其项暴露为标准钥匙串条目。使用属性查询这些条目:
kSecAttrTokenIDswift
import Security
func findTokenKey(tokenID: String) throws -> SecKey {
let query: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrTokenID as String: tokenID,
kSecReturnRef as String: true
]
var result: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status == errSecSuccess, let key = result else {
throw TKError(.objectNotFound)
}
return key as! SecKey
}使用替代以获取跨应用启动仍有效的持久引用。当令牌被移除时,该引用将失效——需处理错误,提示用户重新插入令牌。
kSecReturnPersistentRefkSecReturnReferrSecItemNotFound使用以相同方式查询证书。
kSecClass: kSecClassCertificateCertificate Authentication
证书身份验证
Token Key Requirements
令牌密钥要求
For user login, the token must contain at least one key capable of signing
with: EC signature digest X962, RSA signature digest PSS, or RSA signature
digest PKCS1v15.
For keychain unlock, the token needs:
- 256-bit EC key () supporting
kSecAttrKeyTypeECSECPrimeRandom, orecdhKeyExchangeStandard - 2048/3072/4096-bit RSA key () supporting
kSecAttrKeyTypeRSAdecryptionrsaEncryptionOAEPSHA256
对于用户登录,令牌必须包含至少一个能够使用以下算法签名的密钥:EC签名摘要X962、RSA签名摘要PSS或RSA签名摘要PKCS1v15。
对于钥匙串解锁,令牌需要:
- 256位EC密钥(),支持
kSecAttrKeyTypeECSECPrimeRandom,或ecdhKeyExchangeStandard - 2048/3072/4096位RSA密钥(),支持
kSecAttrKeyTypeRSA解密rsaEncryptionOAEPSHA256
Smart Card Authentication Preferences (macOS)
智能卡身份验证偏好设置(macOS)
Configure in the domain (MDM or systemwide):
com.apple.security.smartcard| Key | Default | Description |
|---|---|---|
| | Enable smart card authentication |
| | Certificate trust level (0-3) |
| | Pair a single smart card to an account |
| | Require smart card for login |
Trust levels: = trust all, = validity + issuer, = + soft
revocation, = + hard revocation.
0123在域中配置(通过MDM或系统级设置):
com.apple.security.smartcard| 键 | 默认值 | 描述 |
|---|---|---|
| | 启用智能卡身份验证 |
| | 证书信任级别(0-3) |
| | 将单个智能卡与账户绑定 |
| | 强制要求使用智能卡登录 |
信任级别: = 信任所有证书, = 验证有效性与颁发者, = 额外验证软吊销, = 额外验证硬吊销。
0123Token Watching
令牌监控
TKTokenWatcherswift
import CryptoTokenKit
final class TokenMonitor {
private let watcher = TKTokenWatcher()
func startMonitoring() {
for tokenID in watcher.tokenIDs {
print("Token present: \(tokenID)")
if let info = watcher.tokenInfo(forTokenID: tokenID) {
print(" Driver: \(info.driverName ?? "unknown")")
print(" Slot: \(info.slotName ?? "unknown")")
}
}
watcher.setInsertionHandler { [weak self] tokenID in
print("Token inserted: \(tokenID)")
self?.watcher.addRemovalHandler({ removedTokenID in
print("Token removed: \(removedTokenID)")
}, forTokenID: tokenID)
}
}
}TKTokenWatcherswift
import CryptoTokenKit
final class TokenMonitor {
private let watcher = TKTokenWatcher()
func startMonitoring() {
for tokenID in watcher.tokenIDs {
print("Token present: \(tokenID)")
if let info = watcher.tokenInfo(forTokenID: tokenID) {
print(" Driver: \(info.driverName ?? "unknown")")
print(" Slot: \(info.slotName ?? "unknown")")
}
}
watcher.setInsertionHandler { [weak self] tokenID in
print("Token inserted: \(tokenID)")
self?.watcher.addRemovalHandler({ removedTokenID in
print("Token removed: \(removedTokenID)")
}, forTokenID: tokenID)
}
}
}Error Handling
错误处理
CryptoTokenKit operations throw . Key error codes:
TKError| Code | Meaning |
|---|---|
| Operation not supported by this token |
| Communication with token failed |
| Data from token is corrupted |
| User canceled the operation |
| PIN or password incorrect |
| Requested key or certificate not found |
| Token is no longer present |
| Authentication required before operation |
CryptoTokenKit操作会抛出。主要错误代码:
TKError| 代码 | 含义 |
|---|---|
| 令牌不支持该操作 |
| 与令牌通信失败 |
| 令牌返回的数据已损坏 |
| 用户取消了操作 |
| PIN或密码错误 |
| 未找到请求的密钥或证书 |
| 令牌已不存在 |
| 执行操作前需要身份验证 |
Common Mistakes
常见误区
DON'T: Query token keychain items without checking token presence
错误做法:未检查令牌存在性就查询令牌钥匙串项
swift
// WRONG -- query may fail if token was removed
let key = try findTokenKey(tokenID: savedTokenID)
// CORRECT -- verify the token is still present first
let watcher = TKTokenWatcher()
guard watcher.tokenIDs.contains(savedTokenID) else {
promptUserToInsertToken()
return
}
let key = try findTokenKey(tokenID: savedTokenID)swift
// WRONG -- query may fail if token was removed
let key = try findTokenKey(tokenID: savedTokenID)
// CORRECT -- verify the token is still present first
let watcher = TKTokenWatcher()
guard watcher.tokenIDs.contains(savedTokenID) else {
promptUserToInsertToken()
return
}
let key = try findTokenKey(tokenID: savedTokenID)DON'T: Assume smart card APIs work on iOS
错误做法:假设智能卡API在iOS上可用
swift
// WRONG -- TKSmartCardSlotManager.default is nil on iOS
let manager = TKSmartCardSlotManager.default! // Crashes on iOS
// CORRECT -- guard availability
guard let manager = TKSmartCardSlotManager.default else {
print("Smart card services unavailable on this platform")
return
}swift
// WRONG -- TKSmartCardSlotManager.default is nil on iOS
let manager = TKSmartCardSlotManager.default! // Crashes on iOS
// CORRECT -- guard availability
guard let manager = TKSmartCardSlotManager.default else {
print("Smart card services unavailable on this platform")
return
}DON'T: Skip session management for card communication
错误做法:跳过卡通信的会话管理
swift
// WRONG -- sending commands without a session
card.transmit(apdu) { response, error in /* may fail */ }
// CORRECT -- use withSession or beginSession/endSession
try card.withSession {
let (sw, response) = try card.send(
ins: 0xCA, p1: 0x00, p2: 0x6E, data: nil, le: 0
)
}swift
// WRONG -- sending commands without a session
card.transmit(apdu) { response, error in /* may fail */ }
// CORRECT -- use withSession or beginSession/endSession
try card.withSession {
let (sw, response) = try card.send(
ins: 0xCA, p1: 0x00, p2: 0x6E, data: nil, le: 0
)
}DON'T: Ignore status words in APDU responses
错误做法:忽略APDU响应中的状态字
swift
// WRONG -- assuming success
let (_, response) = try card.send(ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil)
// CORRECT -- check status word
let (sw, response) = try card.send(ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil)
guard sw == 0x9000 else {
throw SmartCardError.commandFailed(statusWord: sw)
}swift
// WRONG -- assuming success
let (_, response) = try card.send(ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil)
// CORRECT -- check status word
let (sw, response) = try card.send(ins: 0xA4, p1: 0x04, p2: 0x00, data: aid, le: nil)
guard sw == 0x9000 else {
throw SmartCardError.commandFailed(statusWord: sw)
}DON'T: Hard-code blanket algorithm support
错误做法:硬编码支持所有算法
The delegate method must reflect what the hardware actually
implements. Returning unconditionally causes runtime failures when
the system attempts unsupported operations.
supportstruesupportstrueReview Checklist
审核检查清单
- Platform availability verified (macOS-only,
TKSmartCardiOS 14+)TKTokenWatcher - Token extension target uses =
NSExtensionPointIdentifiercom.apple.ctk-tokens - set to the correct driver class in Info.plist
com.apple.ctk.driver-class - Extension registered via launch during installation
_securityagent - checks specific algorithms, not blanket
TKTokenSessionDelegatetrue - Smart card sessions opened and closed (or
withSession/beginSession)endSession - APDU status words checked after every call
send - Token presence verified via before keychain queries
TKTokenWatcher - cases handled with appropriate user feedback
TKError - Keychain contents populated with correct values
objectID - capabilities (
TKTokenKeychainKey,canSign) match hardwarecanDecrypt - Certificate trust level configured appropriately for deployment environment
- handled for persistent references when token is removed
errSecItemNotFound
- 已验证平台可用性(仅支持macOS,
TKSmartCard支持iOS 14+)TKTokenWatcher - 令牌扩展目标的设置为
NSExtensionPointIdentifiercom.apple.ctk-tokens - Info.plist中已设置为正确的驱动类
com.apple.ctk.driver-class - 安装期间通过启动完成扩展注册
_securityagent - 检查具体算法,而非无条件返回
TKTokenSessionDelegatetrue - 智能卡会话已正确打开和关闭(使用或
withSession/beginSession)endSession - 每次调用后都检查了APDU状态字
send - 查询钥匙串前通过验证令牌存在性
TKTokenWatcher - 已处理情况并提供适当的用户反馈
TKError - 钥匙串内容已使用正确的值填充
objectID - 的功能(
TKTokenKeychainKey,canSign)与硬件匹配canDecrypt - 已根据部署环境配置适当的证书信任级别
- 令牌移除时,已处理持久引用的错误
errSecItemNotFound
References
参考资料
- Extended patterns (PIV commands, TLV parsing, generic token drivers, APDU helpers, secure PIN): references/cryptotokenkit-patterns.md
- CryptoTokenKit framework
- TKTokenDriver
- TKToken
- TKTokenSession
- TKSmartCard
- TKSmartCardSlotManager
- TKTokenWatcher
- Authenticating Users with a Cryptographic Token
- Using Cryptographic Assets Stored on a Smart Card
- Configuring Smart Card Authentication
- 扩展模式(PIV命令、TLV解析、通用令牌驱动、APDU助手、安全PIN):references/cryptotokenkit-patterns.md
- CryptoTokenKit framework
- TKTokenDriver
- TKToken
- TKTokenSession
- TKSmartCard
- TKSmartCardSlotManager
- TKTokenWatcher
- Authenticating Users with a Cryptographic Token
- Using Cryptographic Assets Stored on a Smart Card
- Configuring Smart Card Authentication