YubiKit 4.4.0

YubiKit 4.4.0

Jens Utbult维护。



YubiKit 4.4.0

  • Yubico

Yubico Mobile iOS SDK (YubiKit)

YubiKit 是 Yubico 提供的一个 iOS 库,用于与 iOS 设备上的 YubiKey 进行交互。

该库附带一个 示例应用程序,展示了如何将库集成到项目中,并在 iOS 项目中演示了该库的所有功能。

该库的更改记录在 变更日志 中。

关于

YubiKit 需要一个物理密钥来测试其功能。在运行包含的 示例应用程序 或将 YubiKit 集成到您自己的应用程序之前,您需要一个带 NFC 的 YubiKey 或 YubiKey 5Ci 来测试功能。

在 Xcode 工作区内部使用时,主应用程序可以将库构建为目标应用程序目标的依赖项。此外,可以使用项目根目录中提供的 build.sh 脚本来打包库。

过渡到 SDK 4 版本

如果您已经集成了 SDK 的早期版本,请阅读 过渡文档

入门指南

要开始,您可以试用作为此库一部分的演示,或者开始将库集成到您自己的应用中。

试用演示

此库附带了名为 YubiKitDemo 的演示应用程序。应用程序使用 Swift 实现,并展示了如何使用 YubiKit 的多个示例,包括通过附件或 NFC YubiKeys 使用 WebAuthn/FIDO2。

YubiKit 演示应用程序展示了如何将库链接到项目,以便在将其添加到您的项目时进行并列比较。

集成库

YubiKit SDK 以库的形式提供,可以通过 SPM、CocoaPods 或手动设置添加到任何新的或现有的 iOS Xcode 项目中。

[SPM 设置]

iOS 的 YubiKit SDK 可通过 Swift 包管理器 (SPM) 获取。SPM 是内置于最新版本的 Xcode 中的依赖项管理器。点击这里了解详细信息。

  1. 打开 Xcode,然后单击“文件”->“Swift 包”->“添加包依赖项...”

  2. 粘贴以下 URL: https://github.com/Yubico/yubikit-ios

  3. 单击“下一步”->“下一步”->“完成”

  4. 如果您要编译的项目是用 Swift 编写的,您需要通过将 #import <YubiKit.h> 添加到您的桥接头文件来提供 YubiKit 库的桥梁。如果您的项目中不存在桥接头文件,您可以按照以下 文档 添加一个。

[CocoaPods 设置]

可以通过 CocoaPods 获取 iOS 的 YubiKit SDK。CocoaPods 是 Objective-C 和 Swift 的集中式依赖项管理器。点击这里了解详细信息。

将 YubiKit 添加到您的 Podfile

use_frameworks!

pod 'YubiKit', '~> 4.4.0'

如果您想获取最新的更改,可以将最后一行替换为:

pod 'YubiKit', :git => 'https://github.com/Yubico/yubikit-ios.git'

将 YubiKit 添加到您的 Podfile 后,运行 pod install 并用 Xcode 打开 *.xcworkspace

然后导入YubiKit模块,您就可以使用其类和方法了。

import YubiKit

通过跳过手动设置,继续SDK的配置,直至启用自定义闪电协议

手动设置

下载或克隆YubiKit SDK源代码

  1. 下载最新的YubiKit SDK (.zip)到您的桌面

    git clone https://github.com/Yubico/yubikit-ios.git

将YubiKit文件夹添加到您的Xcode项目中

  1. 将整个/YubiKit[版本]/YubiKit文件夹拖拽到您的Xcode项目中。勾选选项如果需要则复制项目。或者将现有的Yubikit项目添加到您的工作区中

链接框架和库

  1. 项目设置 > 通用 > 链接的框架和库中。点击+,并添加libYubiKit.a

头文件搜索路径

  1. 编译设置 > 过滤器按'头文件搜索路径'。将调试和发布都设置为./YubiKit/**(递归)

-ObjC标志

  1. 编译设置 > 过滤器按'其他链接器标志'中添加-ObjC标志到调试和发布。

桥接头

  1. 如果您的目标项目是用Swift编写的,您需要通过在桥接头中添加#import <YubiKit/YubiKit.h>向YubiKit库添加一个桥接。如果项目中不存在桥接头,您可以通过遵循以下文档来添加一个。

启用自定义闪电协议

如果您正在支持通过闪电连接器支持YubiKey 5Ci,则是必需的

YubiKey 5Ci是一种Apple MFi外部配件,通过iAP2进行通信。您正在告诉您的应用程序,所有与5Ci作为支持的外部配件的通信都通过com.yubico.ylp进行。

打开info.plist,并在支持的外部配件协议下添加com.yubico.ylp作为新条目。

启用TKSmartCard支持

为了支持通过USB-C端口连接到的iOS 16或更高版本设备上的YubiKey,您需要在您的应用程序中添加com.apple.security.smartcard权限。请注意,此连接仅支持基于Smart card的应用程序,不支持U2F、FIDO2或OTP。

授予访问NFC

要添加对NFC YubiKey的支持,请按照以下步骤操作

  • 为自iOS 13以来可用的读取NFC特定标记添加一个NEW权限。此新权限在启用目标签名与功能中的Near Field Communication Tag Reading功能时由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>
...
  • 应用程序需要在Info.plist文件中定义它可以连接的应用程序IDAID列表。AID是一种在ISO 7816标签上唯一识别应用程序的方法,通常由一个标准定义。FIDO2和U2F使用大多数符合FIDO标准的NFC密钥(包括YubiKey)上的AIDA0000006472F0001。在添加支持的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>
  • Info.plist还需要使用NFCReaderUsageDescription密钥为NFC使用提供隐私描述。
<key>NFCReaderUsageDescription</key>
<string>The application needs access to NFC reading to communicate with your YubiKey.</string>

授予访问相机

可选:如果您计划使用相机读取OTP的QR码,请打开info.plist并添加以下使用:'隐私 - 相机使用说明' - "此应用程序需要访问Camera以读取QR码"。

文档

YubiKit头文件已进行文档说明,文档可通过阅读头文件或使用Xcode中的QuickHelp(Option + 点击符号)获取。使用该文档详细了解API中的所有方法、属性和参数。如果您对U2F、FIDO2或OATH等特定类别的实现细节感兴趣,请查看./docs部分。

使用库

YubiKit暴露了一个简单且易于使用的API,用于在YubiKey上执行操作。API分为连接会话。支持的连接包括YKFAccessoryConnectionYKFSmartCardConnectionYKFNFCConnection。每个会话通过调用YubiKitManager.shared.startAccessoryConnection()YubikitManager.shared.startSmartCardConnection()YubiKitManager.shared.startNFCConnection()启动。一旦YubiKey连接,SDK将通过YKFManagerDelegate协议提供新的连接。断开连接也会通过协议进行通知。为了获得更简洁、更符合Swift的体验,您可以实现类似以下示例:[YKFManagerDelegate包装](./docs/easy-handling-connections.md)。

从连接中,您可以通过调用方法并传入回调块来获取SDK当前支持的任何会话。通过调用一个方法来获取连接,一旦会话建立并且已选定YubiKey上的相应应用程序,回调将返回新的会话。例如,对于FIDO2会话,它将如下所示

Swift
connection.fido2Session { session, error in
    guard let session = session else { /* handle error and return */ }
    session.verifyPin(pin) { error in
        ...
    }
}
Objective-C
#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。

Swift
if YubiKitDeviceCapabilities.supportsISO7816NFCTags {
    // Provide additional setup when NFC is available            
    // example
    YubiKitManager.shared.startNFCConnection()
} else {
    // Handle the missing NFC support 
}
Objective-C
#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操作。

  • Challenge-response - 提供使用HMAC-SHA1挑战-响应的方法。

  • Management - 提供启用或禁用YubiKey上可用应用程序的能力

  • SmartCardInterface - 提供对Yubikey的低级访问,您可以通过它向密钥发送自定义APDUs。

自定义库

YubiKit 允许通过使用 YubiKitConfigurationYubiKitExternalLocalization 来自定义部分行为。

自定义 YubiKit 行为

为了提供用户界面中显示的消息的本地化字符串,YubiKit 在 YubiKitExternalLocalization 中提供了一组属性。

本地化字符串的一个示例是在设备等待扫描 YubiKey 时,NFC 扫描 UI 中显示的消息。可以通过设置 nfcScanAlertMessage 的值来进行本地化。

Swift
let localizedAlertMessage = NSLocalizedString("NFC_SCAN_MESSAGE", comment: "Scan your YubiKey.")
YubiKitExternalLocalization.nfcScanAlertMessage = localizedAlertMessage
Objective-C
#import <YubiKit/YubiKit.h>
...
NSString *localizedAlertMessage = NSLocalizedString(@"NFC_SCAN_MESSAGE", @"Scan your YubiKey.");
YubiKitExternalLocalization.nfcScanAlertMessage = localizedNfcScanAlertMessage;

有关所有可用属性及其用途,请参阅 YubiKitExternalLocalization 的代码文档。


注意: YubiKitExternalLocalization 提供默认值(英文,en-US),这些值仅适用于调试和原型设计。对于生产代码,始终提供本地化值。


YubiKit FAQ

Q1. YubiKit 是否在设备上存储任何数据?

YubiKit 不会在设备上本地存储任何数据。这包括 NSUserDefaults、应用程序沙盒文件夹和 Keychain。所有执行操作所需的数据都在操作期间存储在内存中,然后丢弃。

Q2. YubiKit 是否会与任何服务进行通信?

YubiKit 并不会与任何服务进行通信,例如网络服务或其他类型的网络通信。YubiKit 是一个用于从 YubiKey 发送、接收和处理数据的库。

Q3. 我能否将 YubiKit 与非 Yubico 制造的设备一起使用?

YubiKit 应仅用于与 Yubico 制造的设备交互。虽然其中一些部分可能与其他设备一起工作,但该库是为与 YubiKeys 一起工作而开发和测试的。当连接到 MFI 配件时,YubiKit 总会检查设备的制造商是否为 Yubico 后才会进行连接。

Q4. YubiKit 是否支持 Bitcode 和位置无关代码的编译?

是的,YubiKit 已编译以适应任何现代 iOS 项目。提供的库是用位置无关代码和 Bitcode 编译的。图书馆的发布版本是优化的(最快,尺寸最小)。

Q5. YubiKit 是否在发布模式下进行日志记录或断言?

不,YubiKit 在发布模式下不会记录日志。从 YubiKit 生成的日志只有在调试构建中才会显示,帮助开发者查看 YubiKit 执行的操作。断言也同理。当向库传递无效参数或密钥出现意外情况时,YubiKit 将在调试模式下进行断言以警告开发者。在发布版本中,库将采用不同的方式处理无效状态(例如,如果对象未正确初始化,则返回 nil,返回错误等)。

Q6. 在哪些版本的 iOS 中 YubiKit 无法正常工作?

YubiKit 应该在 iOS 10 以上任何现代版本的 iOS 上运行,但有少量例外。建议总是让用户升级到最新的 iOS 版本,以防止他们受到已知的旧 iOS 问题的影响。支持 iOS 的最后两个版本(n 和 n-1)通常是一个好习惯,以便将旧版本的 iOS 留在后面。根据苹果的统计,所有 iOS 设备中约 90-95% 运行最新的两个 iOS 版本,因为升级操作系统是免费的,苹果通常为设备提供长达 5 年的升级服务。

* 有些 iOS 版本的 bug 影响了所有外部配件。iOS 11.2 是其中之一,其中应用程序由于 XPC 通信中的一些 bug 无法与配件通信。该 bug 在 iOS 11.2.6 中得到了苹果的修复。因此,在设计和创建应用程序时,建议考虑这些罕见的但可能的 iOS bug。

Q7. 使用 MFi 配件 YubiKey 时,我如何调试应用程序?

从 Xcode 9 开始,IDE 提供了无线调试应用程序的能力。这样,在调试应用程序时就不需要使用物理连接线将设备连接到电脑。这个WWDC 会话解释了 Xcode 中的无线调试功能。

Q8. YubiKey 5Ci 支持USB-C类型的iOS设备吗?

USB-C类型的iOS设备,例如第3代iPad Pro,在使用YubiKey 5Ci或其他类型的USB-C连接的YubiKey时具有有限的支持。操作系统并未正式支持这些设备的外部配件。然而,这些设备支持外部USB键盘,因此密钥的OTP功能可以正常工作,可以使用密钥生成Yubico OTP和HOTP。

其他资源

  1. Xcode 帮助 - 向目标添加功能
  2. Xcode 帮助 - 构建设置参考
  3. 技术问答 QA1490 - 使用类别构建 Objective-C 静态库
  4. 苹果开发者 - Swift 与 Objective-C 同在一个项目中
  5. Yubico - 开发者网站
  6. Yubico - 在线演示 OTP 和 U2F
  7. Yubico - OTP 文档
  8. Yubico - 什么是 U2F?
  9. Yubico - YKOATH 协议规范
  10. FIDO 协盟 - CTAP2 规范
  11. W3.org - 网络身份验证:用于访问公钥凭证的 API