Skip to content

Latest commit

 

History

History
1036 lines (870 loc) · 39.9 KB

File metadata and controls

1036 lines (870 loc) · 39.9 KB

wekey-skf 产品规格说明书

版本: 1.0.0-draft 日期: 2026-02-06 状态: 待评审


1. 项目概述

1.1 项目背景

wekey-skf 是 TrustAsia 密码设备管理工具的 C++/Qt 重构版本,原项目 ts-wekey-skf 基于 Go + CGO + React 实现。

1.2 重构动机

原项目使用 CGO 调用 C 语言 SKF 库,存在以下问题:

  • 内存管理不可控,导致偶发性崩溃
  • 句柄生命周期难以精确管理
  • 跨平台编译链复杂

C++ 可直接调用 C API,彻底解决上述问题。

1.3 项目目标

  1. 功能完整移植 — 实现原项目全部功能
  2. API 完全兼容 — HTTP API 保持向后兼容
  3. 稳定性提升 — 消除内存管理相关的偶发故障
  4. 用户体验优化 — 原生 Qt 桌面界面

1.4 目标用户

用户类型 使用场景
内部运维 批量管理企业密码设备
开发测试 调试 SKF 集成功能
最终客户 管理个人/企业证书

1.5 平台支持

平台 优先级 最低版本
Windows P0 Windows 10
macOS P1 macOS 11 (Big Sur)

2. 系统架构

2.1 架构模式

采用 混合模式:Qt 桌面 GUI + HTTP API Server 并行运行。

┌─────────────────────────────────────────────────────────┐
│                    wekey-skf 应用                        │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────────┐    ┌─────────────────────────────┐ │
│  │   Qt GUI        │    │   HTTP API Server (:9001)   │ │
│  │  (Qt Widgets)   │    │   (兼容原 API)              │ │
│  └────────┬────────┘    └─────────────┬───────────────┘ │
│           │                           │                 │
│           └───────────┬───────────────┘                 │
│                       ▼                                 │
│  ┌─────────────────────────────────────────────────────┐│
│  │              Core Service Layer                     ││
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ ││
│  │  │ Device  │ │   App   │ │Container│ │  Crypto   │ ││
│  │  │ Manager │ │ Manager │ │ Manager │ │  Service  │ ││
│  │  └─────────┘ └─────────┘ └─────────┘ └───────────┘ ││
│  └─────────────────────────┬───────────────────────────┘│
│                            ▼                            │
│  ┌─────────────────────────────────────────────────────┐│
│  │              Driver Plugin System                   ││
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐               ││
│  │  │   SKF   │ │  P11    │ │ Longmai │  ...          ││
│  │  │ Plugin  │ │ Plugin  │ │ Plugin  │               ││
│  │  └────┬────┘ └────┬────┘ └────┬────┘               ││
│  └───────┼───────────┼───────────┼─────────────────────┘│
└──────────┼───────────┼───────────┼──────────────────────┘
           ▼           ▼           ▼
    ┌──────────┐ ┌──────────┐ ┌──────────┐
    │libskf.dll│ │libp11.dll│ │liblm.dll │  (厂商 C 库)
    └──────────┘ └──────────┘ └──────────┘

2.2 模块划分

模块 职责 技术
gui/ Qt Widgets 界面 Qt 6.x Widgets
api/ HTTP REST API Qt Network / QtHttpServer
core/ 业务逻辑层 纯 C++
plugins/ 驱动插件 QPluginLoader
config/ 配置管理 JSON (兼容原格式)
log/ 日志系统 自定义 + Qt 信号

2.3 驱动插件系统

使用 QPluginLoader 实现运行时动态加载:

// 插件接口定义
class IDriverPlugin {
public:
    virtual ~IDriverPlugin() = default;

    // 设备操作
    virtual QList<DeviceInfo> enumDevices(bool login) = 0;
    virtual bool changeDeviceAuth(const QString& devName,
                                  const QString& oldPin,
                                  const QString& newPin) = 0;

    // 应用操作
    virtual QList<AppInfo> enumApps(const QString& devName) = 0;
    virtual bool createApp(const QString& devName,
                          const QString& appName,
                          const QVariantMap& args) = 0;
    virtual bool loginApp(const QString& devName,
                         const QString& appName,
                         const QVariantMap& args) = 0;

    // ... 完整接口见 §3.1
};

3. 功能规格

3.1 驱动插件接口 (IDriverPlugin)

所有驱动必须实现以下接口:

3.1.1 设备管理

方法 参数 返回值 说明
enumDevices login: bool QList<DeviceInfo> 枚举已连接设备
changeDeviceAuth devName, oldPin, newPin bool 修改设备认证密钥
setDeviceLabel devName, label bool 设置设备标签
waitForDeviceEvent - int (事件类型) 监听设备插拔事件

3.1.2 应用管理

方法 参数 返回值 说明
enumApps devName QList<AppInfo> 枚举设备内应用
createApp devName, appName, args bool 创建应用
deleteApp devName, appName bool 删除应用
loginApp devName, appName, args bool 登录应用
logoutApp devName, appName bool 登出应用
updateAppPin devName, appName, args bool 修改应用 PIN
unblockApp devName, appName, args bool 解锁被锁定的 PIN
getRetryCount devName, appName, role int 获取 PIN 剩余尝试次数

createApp 参数说明(args):

  • adminPin (QString): 管理员 PIN 码
  • userPin (QString): 用户 PIN 码
  • adminPinRetryCount (int, 可选): 管理员 PIN 重试次数,默认 6
  • userPinRetryCount (int, 可选): 用户 PIN 重试次数,默认 6
  • createFileRights (int, 可选): 创建文件权限,默认 0

loginApp 参数说明(args):

  • pin (QString): PIN 码
  • role (QString): 角色,"admin" 或 "user"

updateAppPin 参数说明(args):

  • role (QString): 角色,"admin" 或 "user"
  • oldPin (QString): 原 PIN 码
  • newPin (QString): 新 PIN 码

unblockApp 参数说明(args):

  • adminPin (QString): 管理员 PIN 码
  • newUserPin (QString): 新的用户 PIN 码

3.1.3 容器管理

方法 参数 返回值 说明
enumContainers devName, appName QList<ContainerInfo> 枚举容器
createContainer devName, appName, containerName bool 创建容器
deleteContainer devName, appName, containerName bool 删除容器
openContainer devName, appName, containerName bool 打开容器

3.1.4 证书操作

方法 参数 返回值 说明
generateCsr devName, appName, containerName, args QByteArray 生成 CSR
importCertificate devName, appName, containerName, args bool 导入证书(链)
exportCertificate devName, appName, containerName QList<CertInfo> 导出证书
verifyCertificate devName, appName, containerName bool 验证证书
deleteCertificate sn, serial bool 删除证书

CSR 支持的密钥类型:

  • SM2 (sm2p256v1)
  • RSA-2048
  • RSA-3072
  • RSA-4096

证书链支持:

  • 导入时支持完整证书链(根证书 + 中间证书 + 终端证书)
  • 自动解析 PEM/DER 格式
  • 按顺序导入链中各证书

generateCsr 参数说明(args):

  • keyPairType (QString): 密钥对类型
    • "SM2_sm2p256v1": SM2 国密算法
    • "RSA_2048": RSA 2048 位
    • "RSA_3072": RSA 3072 位
    • "RSA_4096": RSA 4096 位
  • cname (QString): 通用名(Common Name)
  • org (QString): 组织(Organization)
  • unit (QString): 部门(Organizational Unit)
  • renew (bool, 可选): 是否重新生成密钥对,默认 false
  • isNonGMCert (bool, 可选): 是否为非国密证书,默认 false
    • 设置为 true 时,使用标准 X.509 格式而非国密格式
    • 仅在密钥类型为 RSA 时有效

importCertificate 参数说明(args):

  • cert (QString): 证书 PEM 格式字符串
  • certChain (QStringList, 可选): 证书链(中间证书和根证书)
  • signFlag (bool, 可选): 是否为签名证书,默认 true

3.1.5 签名与验签

方法 参数 返回值 说明
sign devName, appName, containerName, data QByteArray 数字签名
verify devName, appName, containerName, data, signature bool 验证签名

3.1.6 文件操作

方法 参数 返回值 说明
enumFiles devName, appName QStringList 枚举文件
createFile devName, appName, fileName, data, args bool 创建文件
readFile devName, appName, fileName QByteArray 读取文件
deleteFile devName, appName, fileName bool 删除文件

3.1.7 其他

方法 参数 返回值 说明
generateRandom devName, count QByteArray 生成随机数

3.2 数据结构定义

struct DeviceInfo {
    QString deviceName;      // 设备名称(唯一标识)
    QString devicePath;      // 设备路径
    QString manufacturer;    // 制造商
    QString label;           // 用户标签
    QString serialNumber;    // 序列号
    QString hardwareVersion; // 硬件版本
    QString firmwareVersion; // 固件版本
    bool isLoggedIn;         // 是否已登录
};

struct AppInfo {
    QString appName;         // 应用名称
    bool isLoggedIn;         // 是否已登录
};

struct ContainerInfo {
    QString containerName;   // 容器名称
    bool keyGenerated;       // 是否已生成密钥
    int keyType;             // 密钥类型 (SM2/RSA)
    bool certImported;       // 是否已导入证书
};

struct CertInfo {
    QString serialNumber;    // 证书序列号
    QString subject;         // 主题 DN
    QString commonName;      // 通用名
    QString issuer;          // 颁发者 DN
    QDateTime notBefore;     // 生效时间
    QDateTime notAfter;      // 过期时间
    int certType;            // 证书类型 (签名/加密)
    QString certPem;         // PEM 格式证书
    QString publicKeyHash;   // 公钥哈希
};

3.3 设备热插拔处理

检测机制:

  • 启动后台线程调用 waitForDeviceEvent()
  • 检测到插拔事件后发出 Qt 信号

处理流程:

设备拔出时:
1. 检测到 DEVICE_REMOVED 事件
2. 清理该设备关联的所有句柄 (Device/App/Container)
3. 更新 GUI 设备列表
4. 如果有正在进行的操作,弹窗提示 "设备已断开"
5. 记录日志

设备插入时:
1. 检测到 DEVICE_INSERTED 事件
2. 刷新设备列表
3. 更新 GUI

3.4 PIN 码安全处理

剩余次数显示:

  • 登录对话框显示 "剩余尝试次数: N"
  • 每次 PIN 错误后实时更新

锁定处理:

  • 检测到 SAR_PIN_LOCKED 错误码
  • 弹出解锁对话框,要求输入管理员 PIN
  • 调用 unblockApp() 解锁

4. HTTP API 规格

4.1 概述

  • 基础 URL: http://localhost:9001
  • 协议: HTTP/1.1
  • 数据格式: JSON
  • 字符编码: UTF-8

4.2 公共接口

健康检查

GET /health
Response: { "status": "ok", "version": "1.0.0" }

优雅退出

GET /exit
Response: { "code": 0, "message": "success" }

4.3 业务接口 (/api/v1)

枚举设备

GET /api/v1/enum-dev
Response: {
    "code": 0,
    "message": "success",
    "data": [
        {
            "deviceName": "...",
            "serialNumber": "...",
            "manufacturer": "...",
            "label": "...",
            "hwVersion": "...",
            "firmwareVersion": "...",
            "isLogin": false
        }
    ]
}

登录

POST /api/v1/login
Request: {
    "serialNumber": "...",
    "appName": "TAGM",
    "role": "user",
    "pin": "123456"
}
Response: { "code": 0, "message": "success" }

生成 CSR

POST /api/v1/csr
Request: {
    "serialNumber": "...",
    "appName": "TAGM",
    "containerName": "TrustAsia",
    "keyPairType": "SM2_sm2p256v1",
    "cname": "Common Name",
    "org": "Organization",
    "unit": "Unit"
}
Response: {
    "code": 0,
    "message": "success",
    "data": { "csr": "-----BEGIN CERTIFICATE REQUEST-----\n..." }
}

导入证书

POST /api/v1/import-cert
Request: {
    "serialNumber": "...",
    "appName": "TAGM",
    "containerName": "TrustAsia",
    "cert": "-----BEGIN CERTIFICATE-----\n...",
    "certChain": ["-----BEGIN CERTIFICATE-----\n...", ...]  // 可选,证书链
}
Response: { "code": 0, "message": "success" }

导出证书

GET /api/v1/export-cert?serialNumber=...&appName=...&containerName=...
Response: {
    "code": 0,
    "message": "success",
    "data": [
        {
            "serialNumber": "...",
            "subjectDn": "...",
            "commonName": "...",
            "issuerDn": "...",
            "validity": ["2024-01-01", "2025-01-01"],
            "certType": 1,
            "cert": "-----BEGIN CERTIFICATE-----\n..."
        }
    ]
}

签名

POST /api/v1/sign
Request: {
    "serialNumber": "...",
    "appName": "TAGM",
    "containerName": "TrustAsia",
    "data": "base64编码的待签名数据"
}
Response: {
    "code": 0,
    "message": "success",
    "data": { "signature": "hex编码的签名" }
}

验签

POST /api/v1/verify
Request: {
    "serialNumber": "...",
    "appName": "TAGM",
    "containerName": "TrustAsia",
    "data": "base64编码的原始数据",
    "signature": "hex编码的签名"
}
Response: { "code": 0, "message": "success" }

生成随机数

POST /api/v1/random
Request: { "serialNumber": "...", "length": 32 }
Response: {
    "code": 0,
    "message": "success",
    "data": { "random": "hex编码的随机数" }
}

4.4 管理接口 (/admin)

模块管理

GET    /admin/mod/list              # 列出所有模块
POST   /admin/mod/create            # 添加模块
POST   /admin/mod/active            # 激活模块
DELETE /admin/mod/delete            # 删除模块

设备管理

GET    /admin/dev/list              # 列出设备
POST   /admin/dev/change-auth       # 修改认证密钥
POST   /admin/dev/set-label         # 设置标签

应用管理

GET    /admin/app/list              # 列出应用
POST   /admin/app/create            # 创建应用
DELETE /admin/app/delete            # 删除应用
POST   /admin/app/login             # 登录
POST   /admin/app/logout            # 登出
POST   /admin/app/update-pin        # 修改 PIN
POST   /admin/app/unblock           # 解锁 PIN

容器管理

GET    /admin/container/list        # 列出容器
POST   /admin/container/create      # 创建容器
DELETE /admin/container/delete      # 删除容器
POST   /admin/container/gen-csr     # 生成 CSR
POST   /admin/container/import-cert # 导入证书
GET    /admin/container/export-cert # 导出证书
POST   /admin/container/verify      # 验证证书

文件管理

GET    /admin/file/list             # 列出文件
POST   /admin/file/create           # 创建文件
GET    /admin/file/read             # 读取文件
DELETE /admin/file/delete           # 删除文件

配置管理

GET    /admin/settings/defaults     # 获取默认值
POST   /admin/settings/defaults     # 设置默认值

4.5 错误码定义

错误码 名称 说明
0x00 SUCCESS 成功
0x01 FAIL 通用失败
0x03 INVALID_PARAM 参数无效
0x04 NO_ACTIVE_MODULE 未激活模块
0x09 NOT_LOGGED_IN 未登录
0x0B NOT_AUTHORIZED 未授权
0x24 PIN_INCORRECT PIN 错误
0x25 PIN_LOCKED PIN 已锁定
0x23 DEVICE_REMOVED 设备已移除

5. GUI 规格

5.1 技术选型

  • 框架: Qt 6.x Widgets
  • 布局: 左侧导航 + 右侧内容区
  • 主题: 系统原生风格
  • 语言: 仅中文

5.2 窗口结构

┌─────────────────────────────────────────────────────────┐
│  wekey-skf                                    [_][□][×] │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┬─────────────────────────────────────────┤
│ │             │                                         │
│ │  模块管理   │         (内容区)                         │
│ │  设备管理   │                                         │
│ │  应用管理   │                                         │
│ │  容器管理   │                                         │
│ │  文件管理   │                                         │
│ │  配置管理   │                                         │
│ │             │                                         │
│ │  ─────────  │                                         │
│ │  日志查看   │                                         │
│ │             │                                         │
│ └─────────────┴─────────────────────────────────────────┤
│ 状态栏: [设备: 1 已连接] [模块: SKF 已激活] [API: :9001] │
└─────────────────────────────────────────────────────────┘

5.3 页面详细设计

5.3.1 模块管理页

功能:

  • 显示已注册的驱动模块列表
  • 添加新模块(选择 .dll/.dylib 文件)
  • 删除模块
  • 激活/切换当前模块

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 驱动模块管理                                             │
├─────────────────────────────────────────────────────────┤
│ [+ 添加模块]                                             │
│                                                         │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 名称          路径                      状态   操作  │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ SKF           C:\...\libskf.dll        ● 已激活 [删除]│ │
│ │ Longmai       C:\...\liblm.dll         ○ 未激活 [激活][删除]│
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

5.3.2 设备管理页

功能:

  • 显示已连接设备列表(实时刷新)
  • 查看设备详情
  • 设置设备标签
  • 修改设备认证密钥

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 设备管理                                    [🔄 刷新]   │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 序列号              标签        制造商      操作    │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 1234567890          我的Key     Longmai    [详情][设置]│
│ │ 0987654321          测试设备    Feitian    [详情][设置]│
│ └─────────────────────────────────────────────────────┘ │
│                                                         │
│ 设备详情:                                               │
│   制造商: Longmai                                       │
│   硬件版本: 1.0.0                                       │
│   固件版本: 2.1.0                                       │
└─────────────────────────────────────────────────────────┘

5.3.3 应用管理页

功能:

  • 选择设备后显示应用列表
  • 创建/删除应用
  • 登录/登出应用
  • 修改 PIN
  • 解锁被锁定的 PIN

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 应用管理                                                │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择设备 ▼]                                   │
│                                                         │
│ [+ 创建应用]                                             │
│                                                         │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 应用名称        登录状态        操作                 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ TAGM            ● 已登录        [登出][修改PIN][删除]│ │
│ │ TestApp         ○ 未登录        [登录][修改PIN][删除]│ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

登录对话框:

┌─────────────────────────────┐
│ 登录应用                     │
├─────────────────────────────┤
│ 应用: TAGM                   │
│                             │
│ 角色: ○ 用户  ● 管理员       │
│                             │
│ PIN:  [********]            │
│                             │
│ 剩余尝试次数: 3              │
│                             │
│      [取消]    [登录]        │
└─────────────────────────────┘

5.3.4 容器管理页

功能:

  • 选择设备和应用后显示容器列表
  • 创建/删除容器
  • 生成 CSR
  • 导入/导出证书
  • 验证证书

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 容器管理                                                │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择 ▼]  应用: [下拉选择 ▼]                   │
│                                                         │
│ [+ 创建容器]                                             │
│                                                         │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 容器名称    密钥类型   密钥状态   证书状态   操作    │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ TrustAsia   SM2        ● 已生成   ● 已导入   [操作▼]│ │
│ │ Container2  RSA-2048   ○ 未生成   ○ 未导入   [操作▼]│ │
│ └─────────────────────────────────────────────────────┘ │
│                                                         │
│ 操作菜单: [生成CSR] [导入证书] [导出证书] [验证] [删除] │
└─────────────────────────────────────────────────────────┘

生成 CSR 对话框:

┌─────────────────────────────┐
│ 生成证书请求 (CSR)           │
├─────────────────────────────┤
│ 密钥类型: [SM2 ▼]           │
│   ○ SM2 (sm2p256v1)         │
│   ○ RSA-2048                │
│   ○ RSA-3072                │
│   ○ RSA-4096                │
│                             │
│ 通用名 (CN): [___________]  │
│ 组织 (O):    [___________]  │
│ 部门 (OU):   [___________]  │
│                             │
│ □ 重新生成密钥对 (Renew)     │
│                             │
│     [取消]    [生成]         │
└─────────────────────────────┘

5.3.5 配置管理页

功能:

  • 设置默认应用名、容器名、通用名等
  • 切换错误提示模式(简洁/详细)
  • 配置 HTTP 监听端口

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 配置管理                                                │
├─────────────────────────────────────────────────────────┤
│ 默认值设置                                              │
│   默认应用名:    [TAGM___________]                      │
│   默认容器名:    [TrustAsia______]                      │
│   默认通用名:    [TrustAsia______]                      │
│   默认组织:      [TrustAsia______]                      │
│   默认部门:      [GMCA___________]                      │
│   默认角色:      [● 用户  ○ 管理员]                     │
│                                                         │
│ 系统设置                                                │
│   HTTP 端口:     [9001]                                 │
│   错误提示:      [● 简洁  ○ 详细]                       │
│   日志级别:      [Info ▼]                               │
│                                                         │
│                              [恢复默认]    [保存]        │
└─────────────────────────────────────────────────────────┘

5.3.6 日志查看页

功能:

  • 实时显示应用日志
  • 搜索/过滤日志
  • 按级别过滤(Debug/Info/Warn/Error)

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 日志查看                                                │
├─────────────────────────────────────────────────────────┤
│ 搜索: [_______________] 级别: [All ▼] [🔄 清空]         │
│                                                         │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 2024-01-15 10:30:15 [INFO]  设备已连接: 1234567890 │ │
│ │ 2024-01-15 10:30:16 [INFO]  HTTP Server 启动: :9001│ │
│ │ 2024-01-15 10:30:20 [DEBUG] 枚举设备完成, 共 1 个   │ │
│ │ 2024-01-15 10:31:05 [ERROR] PIN 错误, 剩余 2 次     │ │
│ │ ...                                                 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

5.3.7 文件管理页

功能:

  • 显示设备应用内的文件列表
  • 创建/上传文件到设备
  • 读取/下载文件到本地
  • 删除文件

界面元素:

┌─────────────────────────────────────────────────────────┐
│ 文件管理                                    [+ 创建文件] │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择设备 ▼]  应用: [下拉选择应用 ▼]           │
│                                                         │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 文件名              大小        操作                 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ config.dat          1.2 KB      [读取][删除]        │ │
│ │ userdata.bin        5.8 KB      [读取][删除]        │ │
│ │ settings.txt        0.5 KB      [读取][删除]        │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

创建文件对话框:

┌─────────────────────────────┐
│ 创建文件                     │
├─────────────────────────────┤
│ 文件名: [___________]        │
│                             │
│ 文件: [浏览...]              │
│       已选择: data.bin       │
│       大小: 2.5 KB           │
│                             │
│ 读权限: [Everyone ▼]        │
│ 写权限: [UserOnly ▼]        │
│                             │
│ ⚠️ 文件大小不能超过 8KB      │
│                             │
│      [取消]    [创建]        │
└─────────────────────────────┘

说明:

  • 文件大小限制:8KB(SKF 规范限制)
  • 读权限选项:Everyone / UserOnly / AdminOnly
  • 写权限选项:Everyone / UserOnly / AdminOnly
  • 读取文件时弹出保存对话框,选择本地保存位置
  • 删除操作需要二次确认

5.4 系统托盘

行为:

  • 关闭窗口时最小化到托盘(不退出)
  • 托盘图标右键菜单:
    • 显示主窗口
    • 退出

托盘图标状态:

  • 正常状态:标准图标
  • 有设备连接时:可选择显示设备数量角标

5.5 错误提示

简洁模式(默认):

┌─────────────────────────────┐
│ ⚠️ 操作失败                  │
│                             │
│ PIN 错误,剩余 2 次尝试机会  │
│                             │
│              [确定]          │
└─────────────────────────────┘

详细模式:

┌─────────────────────────────┐
│ ⚠️ 操作失败                  │
│                             │
│ PIN 错误,剩余 2 次尝试机会  │
│                             │
│ 错误码: 0x0A000024          │
│ 函数: SKF_VerifyPIN         │
│ 设备: 1234567890            │
│                             │
│              [确定]          │
└─────────────────────────────┘

6. 配置文件规格

6.1 文件位置

  • 路径: ~/.wekeytool.json
  • 格式: JSON
  • 编码: UTF-8

6.2 配置结构

{
    "version": "1.0.0",
    "listen_port": ":9001",
    "log_level": "info",
    "log_path": "/tmp/wekeytool",
    "systray_disabled": false,
    "mod_paths": {
        "skf": "/path/to/libskf.dll",
        "longmai": "/path/to/liblm.dll"
    },
    "actived_mod_name": "skf",
    "error_mode": "simple",
    "defaults": {
        "appName": "TAGM",
        "containerName": "TrustAsia",
        "commonName": "TrustAsia",
        "organization": "TrustAsia Technologies, Inc.",
        "unit": "GMCA",
        "role": "user"
    }
}

6.3 配置项说明

字段 类型 默认值 说明
version string "1.0.0" 配置版本
listen_port string ":9001" HTTP 监听端口
log_level string "info" 日志级别 (debug/info/warn/error)
log_path string 临时目录 日志文件目录
systray_disabled bool false 是否禁用系统托盘
mod_paths object {} 已注册模块路径映射
actived_mod_name string "" 当前激活的模块名
error_mode string "simple" 错误提示模式 (simple/detailed)
defaults object 见下 默认值配置

7. 非功能需求

7.1 性能

指标 目标
应用启动时间 < 2 秒
设备枚举响应 < 500 毫秒
签名操作响应 < 1 秒
内存占用 < 100 MB (空闲时)

7.2 安全性

  • PIN 码在内存中不明文存储
  • PIN 输入框使用密码掩码
  • 日志中不记录敏感信息(PIN、私钥)
  • 通信仅限本地 (localhost)

7.3 可靠性

  • 设备热插拔不导致崩溃
  • 所有 SKF 调用错误码正确处理
  • 句柄泄漏检测(Debug 模式)

7.4 兼容性

  • 配置文件向后兼容原 Go 版本
  • HTTP API 100% 兼容原 Go 版本

8. 分发与部署

8.1 Windows

  • 分发形式: 绿色版 (Portable)
  • 目录结构:
    wekey-skf/
    ├── wekey-skf.exe       # 主程序
    ├── Qt6Core.dll         # Qt 运行时
    ├── Qt6Widgets.dll
    ├── Qt6Network.dll
    ├── plugins/            # 驱动插件
    │   └── skf.dll
    └── lib/                # 内嵌厂商库
        └── libskf.dll
    

8.2 macOS

  • 分发形式: DMG 安装包
  • 目录结构:
    wekey-skf.app/
    └── Contents/
        ├── MacOS/
        │   └── wekey-skf   # 主程序
        ├── Frameworks/     # Qt 框架
        ├── PlugIns/        # 驱动插件
        └── Resources/      # 内嵌厂商库
            └── lib/
                └── libskf.dylib
    

8.3 单实例控制

  • 使用 QLockFile 或命名互斥量
  • 检测到已有实例时:激活现有窗口,退出新实例
  • 端口冲突时:弹窗提示,引导用户关闭占用程序或修改端口

9. 开发里程碑建议

阶段 内容
M1: 基础框架 项目结构、构建系统、插件接口定义
M2: SKF 驱动 SKF 插件实现、C API 封装
M3: 核心功能 设备/应用/容器管理、证书操作
M4: HTTP API REST API 实现、兼容性测试
M5: GUI 实现 Qt Widgets 界面、系统托盘
M6: 测试与打包 集成测试、安装包制作

附录 A: SKF 错误码映射

SKF 错误码 名称 说明
0x00000000 SAR_OK 成功
0x0A000001 SAR_FAIL 失败
0x0A000002 SAR_UNKNOWNERR 未知错误
0x0A000003 SAR_NOTSUPPORTYETERR 不支持
0x0A000004 SAR_FILEERR 文件错误
0x0A000005 SAR_INVALIDHANDLEERR 无效句柄
0x0A000006 SAR_INVALIDPARAMERR 无效参数
0x0A000023 SAR_DEVICE_REMOVED 设备已移除
0x0A000024 SAR_PIN_INCORRECT PIN 错误
0x0A000025 SAR_PIN_LOCKED PIN 已锁定
0x0A00002D SAR_USER_NOT_LOGGED_IN 用户未登录
0x0A00002E SAR_APPLICATION_NOT_EXISTS 应用不存在

附录 B: 术语表

术语 说明
SKF 智能密码钥匙密码应用接口 (国密标准)
SM2 国密椭圆曲线公钥密码算法
SM3 国密杂凑算法
SM4 国密分组密码算法
CSR Certificate Signing Request (证书签名请求)
PIN Personal Identification Number (个人识别码)
容器 密钥对和证书的存储单元
应用 设备内的逻辑分区,包含多个容器

文档结束