使用 Python 脚本将 CanoKey 恢复出厂设置

与我大多数技术文章的写作方式不同——那些文章通常先由我本人撰写,再借助 LLM 润色,本文大部分内容由 LLM 撰写。我借助 LLM 找到了一种解决方案,确认它能够正常工作,然后将 LLM 的回答整理成了这篇文章。

我在搭载固件 3.0.3-0-g30917b92 的 CanoKey Canary 上测试了以下操作流程。

1. 准备所需工具

在 Debian 或 Ubuntu 上运行:

$ sudo apt install python3-usb libusb-1.0-0

然后使用以下脚本发送命令:

#!/usr/bin/env python3

import time
import usb.core
import usb.util

VID = 0x20A0
PID = 0x42D4
INTERFACE = 1


def apdu(device: usb.core.Device, command: str) -> bytes:
    data = bytes.fromhex(command)

    # Send command APDU.
    device.ctrl_transfer(
        0x41,       # Host-to-device | Vendor | Interface
        0x00,       # CMD
        0x0000,
        INTERFACE,
        data,
    )

    # Wait for execution to finish.
    while True:
        status = device.ctrl_transfer(
            0xC1,       # Device-to-host | Vendor | Interface
            0x02,       # STAT
            0x0000,
            INTERFACE,
            1,
        )

        if bytes(status)[0] == 0x00:
            break

        time.sleep(0.05)

    # Retrieve response APDU.
    response = device.ctrl_transfer(
        0xC1,
        0x01,       # RESP
        0x0000,
        INTERFACE,
        1500,
    )

    return bytes(response)


def main() -> None:
    device = usb.core.find(idVendor=VID, idProduct=PID)

    if device is None:
        raise SystemExit("CanoKey 20A0:42D4 not found")

    print(f"Found {VID:04X}:{PID:04X}")

    while True:
        command = input("> ")
        if command == "":
            break
        response = apdu(device, command)
        print(f"< {response.hex(' ').upper()}")


if __name__ == "__main__":
    main()

2. 选择 Admin 应用

Admin 应用的应用标识符(AID)为 F000000000。发送:

00 A4 04 00 05 F0 00 00 00 00

预期响应:

90 00

这表示 Admin 应用已成功选中。

3. 耗尽 Admin PIN 的重试次数

如果无法通过正常身份验证执行重置,文档规定的恢复出厂设置流程要求执行此步骤。

首先,使用以下命令查询计数器:

00 20 00 00

设备最初应返回:

63 C3

这表示还剩三次尝试机会。

将以下带有错误 PIN 的 APDU 发送三次:

00 20 00 00 06 30 30 30 30 30 30

这些 PIN 字节表示 000000。预期响应如下:

  1. 63 C2(还剩两次尝试)
  2. 63 C1(还剩一次尝试)
  3. 69 83(PIN 已锁定)

重要提示:如果你仍需要正常使用当前 PIN,请不要耗尽重试次数。在本流程中,主动锁定 PIN 是启用锁定状态下恢复出厂设置流程的前提。

4. 发送恢复出厂设置命令

再次运行 WebUSB 脚本,并在发送重置 APDU 之前选中 Admin 应用:

00 A4 04 00 05 F0 00 00 00 00
00 50 00 00 05 52 45 53 45 54

第二条 APDU 是恢复出厂设置命令:

00 50 00 00 05 RESET

其中,RESET 是由五个字节组成的 ASCII 字符串 52 45 53 45 54。CanoKey 将此指令定义为 INS=50;执行前必须先锁定 Admin PIN。

5. 按 LED 提示操作

发送命令后,CanoKey 会开始闪烁。

  1. 看到设备闪烁时,立即触摸设备。
  2. 当设备依次出现快速和缓慢的闪烁时,继续按照提示触摸。
  3. 保持设备连接,让 Python 脚本继续轮询。
  4. 等待脚本返回最终响应:
90 00

最终的 90 00 表示操作成功。完成反复触摸的序列后,设备会返回该响应。

完整流程一览

选择 Admin 应用

00 A4 04 00 05 F0 00 00 00 00

锁定 Admin PIN

将 00 20 00 00 06 30 30 30 30 30 30 发送三次。

开始恢复出厂设置

00 50 00 00 05 52 45 53 45 54

持续触摸,直到重置完成

按照每次闪烁的提示操作,直到收到 90 00。

使用 Hugo 构建
主题 Stack 由 Jimmy 设计