YubiKit 是 Yubico 提供的 iOS 库,用于与 iOS 设备上的 YubiKey 进行交互。
该库提供了一个 演示应用程序,其中展示了如何集成该库的完整示例,并演示了该库在 iOS 项目中的所有功能。
此库的更改记录在此 变更日志 中。
YubiKit 需要一个物理密钥来测试其功能。在运行随附的 演示应用程序 或将 YubiKit 集成到您自己的应用程序之前,您需要一个支持 NFC 的 YubiKey 或一个 YubiKey 5Ci 来测试功能。
当在 Xcode 工作区中使用时,宿主应用程序可以将该库构建为应用程序目标的依赖项。此外,可以使用此项目根文件夹中提供的 build.sh
脚本来打包该库。
如果您已经集成了先前版本的 SDK,请阅读 迁移文档。
要开始使用,您可以尝试作为此库一部分的 演示,或者开始将该库集成到您自己的应用程序中。
该库提供了一个演示应用程序,YubiKitDemo。该应用程序用 Swift 实现,展示了如何使用 YubiKit 的几个示例,包括通过配件或 NFC YubiKey 进行的 WebAuthn/FIDO2。
YubiKit 演示应用程序展示了如何将该库链接到项目中,因此在将该库添加到您自己的项目时,可以进行并排比较。
YubiKit SDK 可作为库使用,可以通过 SPM、Cocoapods 或手动设置添加到任何新的或现有的 iOS Xcode 项目中。
[SPM 设置]
适用于 iOS 的 YubiKit SDK 可以通过 Swift Package Manager (SPM) 获得。 SPM 是 Xcode 最新版本中内置的依赖项管理器。 点击 这里 了解更多信息。
打开 Xcode,点击 "File" -> "Swift Packages" -> "Add Package Dependency..."
点击 "Next" -> "Next" -> "Finish"
如果您的目标项目是用 Swift 编写的,则需要通过将 #import <YubiKit.h>
添加到您的桥接头文件来为 YubiKit 库提供一个桥接。如果您的项目中不存在桥接头文件,您可以按照此 文档 添加一个。
[Cocoapods 设置]
适用于 iOS 的 YubiKit SDK 可以通过 CocoaPods 获得。 CocoaPods 是 Objective-C 和 Swift 的集中式依赖项管理器。 点击 这里 了解更多信息。
将 YubiKit 添加到您的 Podfile 中。
use_frameworks!
pod 'YubiKit', '~> 4.6.0'
如果您想要获得最新的更改,请将最后一行替换为
pod 'YubiKit', :git => 'https://github.com/Yubico/yubikit-ios.git'
将 YubiKit 添加到您的 Podfile
后,运行 pod install
并使用 Xcode 打开 *.xcworkspace
。
然后导入 YubiKit 模块,您就可以使用它的类和方法了。
import YubiKit
跳过 手动设置
,继续执行 启用自定义闪电协议
,完成 SDK 设置。
下载或克隆 YubiKit SDK 源代码
下载 最新的 YubiKit SDK (.zip) 到您的桌面 或者
git clone https://github.com/Yubico/yubikit-ios.git
将 YubiKit 文件夹添加到您的 Xcode 项目
/YubiKit[version]/YubiKit
文件夹拖到您的 Xcode 项目中。选中 如果需要,复制项目 选项。或者将现有的 Yubikit 项目添加到您的工作区链接框架和库
项目设置
> 通用
> 链接框架和库
。点击 + 并添加 libYubiKit.a
头文件搜索路径
构建设置
> 按 '头文件搜索路径' 过滤。将 Debug & Release 都设置为 ./YubiKit/**
(递归)-ObjC 标志
构建设置
> 按 '其他链接器标志' 过滤。将 -ObjC
标志添加到 Debug 和 Release。桥接头文件
#import <YubiKit/YubiKit.h>
添加到您的桥接头文件来为 YubiKit 库提供一个桥接。如果您的项目中不存在桥接头文件,您可以按照此 文档 添加一个。启用自定义闪电协议
如果您支持通过 Lightning 连接器的 YubiKey 5Ci,则 必须
执行此操作。
YubiKey 5Ci 是一种 Apple MFi 外部配件,通过 iAP2 进行通信。您需要告诉您的应用程序,与 5Ci 作为受支持的外部配件的所有通信都通过
com.yubico.ylp
进行。
打开 info.plist 并添加 com.yubico.ylp
作为 Supported external accessory protocols
下的新项目
启用 TKSmartCard 支持
为了支持通过运行 iOS 16 或更高版本的设备上的 USB-C 端口连接的 YubiKey,您需要将 com.apple.security.smartcard
授权添加到您的应用程序。 请注意,此连接仅支持 YubiKey 上基于智能卡的应用程序,不支持 U2F、FIDO2 或 OTP。
授予 NFC 访问权限
要在您的应用程序中添加对 NFC YubiKey 的支持,请按照以下步骤操作
新
授权。 当在目标 签名与功能 中启用 近场通信标签读取 功能时,Xcode 会自动添加此新授权。 启用该功能后,.entitlements 文件需要包含 com.apple.developer.nfc.readersession.formats
授权...
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string> // Application specific tag, including ISO 7816 Tags
</array>
</dict>
...
应用程序 ID
或 AID
的列表。 AID
是一种唯一标识 ISO 7816 标签上应用程序的方式,通常由标准定义。 FIDO2 和 U2F 在大多数符合 FIDO 标准的 NFC 密钥(包括 YubiKey)上使用 AID A0000006472F0001
。 添加支持的 AID 列表后,Info.plist 条目应如下所示<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A000000527471117</string> // YubiKey Management Application AID
<string>A0000006472F0001</string> // FIDO/U2F AID
<string>A0000005272101</string> // OATH AID
<string>A000000308</string> // PIV AID
<string>A000000527200101</string> // YubiKey application/OTP AID (for HMAC SHA1 challenge-response)
</array>
</plist>
<key>NFCReaderUsageDescription</key>
<string>The application needs access to NFC reading to communicate with your YubiKey.</string>
授予相机访问权限
可选:如果您计划使用相机读取 OTP 的 QR 码,请打开 info.plist 并添加以下用法:'Privacy - Camera Usage Description' - "This application needs access to Camera for reading QR codes."
YubiKit 标头已记录在案,该文档可以通过阅读头文件或使用 Xcode 中的 QuickHelp(Option + Click 符号)获得。 使用此文档可以更详细地解释 API 中的所有方法、属性和参数。 如果您对 U2F、FIDO2 或 OATH 等特定类别的实现细节感兴趣,请查看 ./docs 部分。
YubiKit 公开了一个简单易用的 API,用于在 YubiKey 上执行操作。 该 API 分为 Connections
和 Sessions
。 支持的连接是 YKFAccessoryConnection
、YKFSmartCardConnection
和 YKFNFCConnection
。 每个会话都通过调用 YubiKitManager.shared.startAccessoryConnection()
、YubikitManager.shared.startSmartCardConnection()
或 YubiKitManager.shared.startNFCConnection()
来启动。 一旦 YubiKey 连接,SDK 将通过 YKFManagerDelegate
协议传递新连接。 断开连接也通过该协议发出信号。 为了获得更简单和更像 Swift 的体验,您可以实现类似于此示例的内容:YKFManagerDelegate 包装器。
从连接中,您可以检索 SDK 中当前支持的任何会话。 这些连接通过调用带有回调块的方法来获取。 一旦建立了会话,并且选择了 YubiKey 上的相应应用程序,回调将返回新会话。 例如,一个 FIDO2 会话将如下所示
connection.fido2Session { session, error in
guard let session = session else { /* handle error and return */ }
session.verifyPin(pin) { error in
...
}
}
#import <YubiKit/YubiKit.h>
[self.connection fido2Session:^(YKFFIDO2Session * _Nullable session, NSError * _Nullable error) {
if (error) { /* handle error and return */ }
[session verifyPin:pin completion:^(NSError * _Nullable error) {
...
}];
}];
在启动配件连接之前,应用程序应验证运行该应用程序的设备是否支持通过 Lightning 端口连接到 YubiKey。 这可以通过查看 YubiKitDeviceCapabilities
上的 supportsMFIAccessoryKey
属性来完成。
NFC 连接也是如此,与配件连接类似,YubiKitDeviceCapabilities
具有一个属性 supportsISO7816NFCTags
,指示设备是否支持通过 NFC 连接到 YubiKey。
if YubiKitDeviceCapabilities.supportsISO7816NFCTags {
// Provide additional setup when NFC is available
// example
YubiKitManager.shared.startNFCConnection()
} else {
// Handle the missing NFC support
}
#import <YubiKit/YubiKit.h>
...
// NFC scanning is available
if (YubiKitDeviceCapabilities.supportsISO7816NFCTags) {
// Provide additional setup when NFC is available
} else {
// Handle the missing NFC support
}
会话列表记录如下,其中包含其自身的特性和示例
FIDO - 提供可通过 YKFFIDO2Session 访问的 FIDO2 操作。
U2F - 提供可通过 YKFU2FSession 访问的 U2F 操作。
OATH - 允许应用程序(例如身份验证器应用程序)在 YubiKey 上存储 OATH TOTP 和 HOTP 密钥,并生成一次性密码。
OTP - 提供实现类,以通过配件 (5Ci) 或 NFC 获取 YubiKey OTP。
PIV - 提供可通过 YKFPIVSession 访问的 PIV 操作。
挑战-响应 - 提供使用 HMAC-SHA1 挑战-响应的方法。
管理 - 提供启用或禁用 YubiKey 上可用应用程序的功能
SmartCardInterface - 提供对 Yubikey 的低级别访问,您可以使用它将自定义 APDU 发送到密钥
YubiKit 允许使用 YubiKitConfiguration
和 YubiKitExternalLocalization
自定义其某些行为。
为了为库显示的用户面向的消息提供本地化字符串,YubiKit 在 YubiKitExternalLocalization
中提供了一组属性。
本地化字符串的一个示例是 NFC 扫描 UI 中显示的消息,当设备等待扫描 YubiKey 时。 可以通过设置 nfcScanAlertMessage
的值来本地化此消息
let localizedAlertMessage = NSLocalizedString("NFC_SCAN_MESSAGE", comment: "Scan your YubiKey.")
YubiKitExternalLocalization.nfcScanAlertMessage = localizedAlertMessage
#import <YubiKit/YubiKit.h>
...
NSString *localizedAlertMessage = NSLocalizedString(@"NFC_SCAN_MESSAGE", @"Scan your YubiKey.");
YubiKitExternalLocalization.nfcScanAlertMessage = localizedNfcScanAlertMessage;
对于所有可用的属性及其用法,请查看 YubiKitExternalLocalization
的代码文档。
注意: YubiKitExternalLocalization
提供英语 (en-US) 的默认值,这些值仅对调试和原型设计有用。 对于生产代码,请始终提供本地化值。
Yubikit 不会在设备本地存储任何数据。 这包括 NSUserDefaults、应用程序沙箱文件夹和钥匙串。 执行操作所需的所有数据都存储在内存中,持续时间为操作持续时间,然后丢弃。
Yubikit 不与任何服务通信,例如 Web 服务或其他类型的网络通信。 YubiKit 是一个用于发送、接收和处理来自 YubiKey 的数据的库。
YubiKit 是一个库,仅应用于与 Yubico 制造的设备进行交互。虽然它的某些部分可能与其他设备兼容,但此库的开发和测试都是基于 YubiKey。 当连接 MFI 配件时,YubiKit 总是会先检查设备的制造商是否为 Yubico,然后再建立连接。
是的,YubiKit 的编译能够适应任何现代 iOS 项目。提供的库已编译为支持位置无关代码和 Bitcode。该库的发布版本经过优化(速度最快,体积最小)。
不会,YubiKit 在发布模式下不进行日志记录。YubiKit 的日志只会显示在调试版本中,以帮助开发者了解 YubiKit 的工作方式。断言也是如此。 YubiKit 将在调试模式下进行断言,以警告开发者何时将无效参数传递给库,或者当密钥发生意外情况时。 在发布版本中,该库将以不同的方式处理无效状态(例如,如果对象未正确初始化则返回 nil,返回错误等)。
YubiKit 应适用于任何现代版本的 iOS (10+),但有一些例外情况 *。 建议始终要求用户升级到最新版本的 iOS,以保护他们免受已知的旧 iOS 问题的困扰。 支持最新的 2 个 iOS 版本(n 和 n-1)通常是使旧版本 iOS 淘汰的最佳实践。 根据 Apple 统计数据,约 90-95% 的所有 iOS 设备都在运行最新的 2 个 iOS 版本,因为升级操作系统是免费的,并且 Apple 通常会为设备提供 5 年的升级服务。
* 某些版本的 iOS 存在影响所有外部配件的错误。 iOS 11.2 就是其中之一,由于 XPC 通信中的一些错误,应用程序无法与配件通信。 Apple 在 iOS 11.2.6 中修复了此错误。 因此,在设计应用程序时,建议考虑罕见但可能发生的 iOS 错误。
从 Xcode 9 开始,IDE 提供了无线调试应用程序的功能。 这样,物理连接器就无需用于将设备连接到计算机进行调试应用程序。 这个 WWDC 会议 解释了 Xcode 中的无线调试功能。
当使用 YubiKey 5Ci 或其他带有 USB-C 连接器的 YubiKey 类型时,USB-C 型 iOS 设备(例如 iPad Pro 第 3 代)的支持有限。 操作系统未正式支持这些设备上的外部配件。 但是,这些设备支持外部 USB 键盘,因此密钥的 OTP 功能将起作用,并且该密钥可用于生成 Yubico OTP 和 HOTP。