版本: 1.0.0-draft 日期: 2026-02-06 状态: 待评审
wekey-skf 是 TrustAsia 密码设备管理工具的 C++/Qt 重构版本,原项目 ts-wekey-skf 基于 Go + CGO + React 实现。
原项目使用 CGO 调用 C 语言 SKF 库,存在以下问题:
- 内存管理不可控,导致偶发性崩溃
- 句柄生命周期难以精确管理
- 跨平台编译链复杂
C++ 可直接调用 C API,彻底解决上述问题。
- 功能完整移植 — 实现原项目全部功能
- API 完全兼容 — HTTP API 保持向后兼容
- 稳定性提升 — 消除内存管理相关的偶发故障
- 用户体验优化 — 原生 Qt 桌面界面
| 用户类型 | 使用场景 |
|---|---|
| 内部运维 | 批量管理企业密码设备 |
| 开发测试 | 调试 SKF 集成功能 |
| 最终客户 | 管理个人/企业证书 |
| 平台 | 优先级 | 最低版本 |
|---|---|---|
| Windows | P0 | Windows 10 |
| macOS | P1 | macOS 11 (Big Sur) |
采用 混合模式: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 库)
└──────────┘ └──────────┘ └──────────┘
| 模块 | 职责 | 技术 |
|---|---|---|
gui/ |
Qt Widgets 界面 | Qt 6.x Widgets |
api/ |
HTTP REST API | Qt Network / QtHttpServer |
core/ |
业务逻辑层 | 纯 C++ |
plugins/ |
驱动插件 | QPluginLoader |
config/ |
配置管理 | JSON (兼容原格式) |
log/ |
日志系统 | 自定义 + Qt 信号 |
使用 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
};所有驱动必须实现以下接口:
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
enumDevices |
login: bool |
QList<DeviceInfo> |
枚举已连接设备 |
changeDeviceAuth |
devName, oldPin, newPin |
bool |
修改设备认证密钥 |
setDeviceLabel |
devName, label |
bool |
设置设备标签 |
waitForDeviceEvent |
- | int (事件类型) |
监听设备插拔事件 |
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
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 重试次数,默认 6userPinRetryCount(int, 可选): 用户 PIN 重试次数,默认 6createFileRights(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 码
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
enumContainers |
devName, appName |
QList<ContainerInfo> |
枚举容器 |
createContainer |
devName, appName, containerName |
bool |
创建容器 |
deleteContainer |
devName, appName, containerName |
bool |
删除容器 |
openContainer |
devName, appName, containerName |
bool |
打开容器 |
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
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, 可选): 是否重新生成密钥对,默认 falseisNonGMCert(bool, 可选): 是否为非国密证书,默认 false- 设置为 true 时,使用标准 X.509 格式而非国密格式
- 仅在密钥类型为 RSA 时有效
importCertificate 参数说明(args):
cert(QString): 证书 PEM 格式字符串certChain(QStringList, 可选): 证书链(中间证书和根证书)signFlag(bool, 可选): 是否为签名证书,默认 true
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
sign |
devName, appName, containerName, data |
QByteArray |
数字签名 |
verify |
devName, appName, containerName, data, signature |
bool |
验证签名 |
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
enumFiles |
devName, appName |
QStringList |
枚举文件 |
createFile |
devName, appName, fileName, data, args |
bool |
创建文件 |
readFile |
devName, appName, fileName |
QByteArray |
读取文件 |
deleteFile |
devName, appName, fileName |
bool |
删除文件 |
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
generateRandom |
devName, count |
QByteArray |
生成随机数 |
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; // 公钥哈希
};检测机制:
- 启动后台线程调用
waitForDeviceEvent() - 检测到插拔事件后发出 Qt 信号
处理流程:
设备拔出时:
1. 检测到 DEVICE_REMOVED 事件
2. 清理该设备关联的所有句柄 (Device/App/Container)
3. 更新 GUI 设备列表
4. 如果有正在进行的操作,弹窗提示 "设备已断开"
5. 记录日志
设备插入时:
1. 检测到 DEVICE_INSERTED 事件
2. 刷新设备列表
3. 更新 GUI
剩余次数显示:
- 登录对话框显示 "剩余尝试次数: N"
- 每次 PIN 错误后实时更新
锁定处理:
- 检测到
SAR_PIN_LOCKED错误码 - 弹出解锁对话框,要求输入管理员 PIN
- 调用
unblockApp()解锁
- 基础 URL:
http://localhost:9001 - 协议: HTTP/1.1
- 数据格式: JSON
- 字符编码: UTF-8
GET /health
Response: { "status": "ok", "version": "1.0.0" }
GET /exit
Response: { "code": 0, "message": "success" }
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" }
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编码的随机数" }
}
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 # 设置默认值
| 错误码 | 名称 | 说明 |
|---|---|---|
| 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 | 设备已移除 |
- 框架: Qt 6.x Widgets
- 布局: 左侧导航 + 右侧内容区
- 主题: 系统原生风格
- 语言: 仅中文
┌─────────────────────────────────────────────────────────┐
│ wekey-skf [_][□][×] │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┬─────────────────────────────────────────┤
│ │ │ │
│ │ 模块管理 │ (内容区) │
│ │ 设备管理 │ │
│ │ 应用管理 │ │
│ │ 容器管理 │ │
│ │ 文件管理 │ │
│ │ 配置管理 │ │
│ │ │ │
│ │ ───────── │ │
│ │ 日志查看 │ │
│ │ │ │
│ └─────────────┴─────────────────────────────────────────┤
│ 状态栏: [设备: 1 已连接] [模块: SKF 已激活] [API: :9001] │
└─────────────────────────────────────────────────────────┘
功能:
- 显示已注册的驱动模块列表
- 添加新模块(选择 .dll/.dylib 文件)
- 删除模块
- 激活/切换当前模块
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 驱动模块管理 │
├─────────────────────────────────────────────────────────┤
│ [+ 添加模块] │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 名称 路径 状态 操作 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ SKF C:\...\libskf.dll ● 已激活 [删除]│ │
│ │ Longmai C:\...\liblm.dll ○ 未激活 [激活][删除]│
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
功能:
- 显示已连接设备列表(实时刷新)
- 查看设备详情
- 设置设备标签
- 修改设备认证密钥
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 设备管理 [🔄 刷新] │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 序列号 标签 制造商 操作 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 1234567890 我的Key Longmai [详情][设置]│
│ │ 0987654321 测试设备 Feitian [详情][设置]│
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 设备详情: │
│ 制造商: Longmai │
│ 硬件版本: 1.0.0 │
│ 固件版本: 2.1.0 │
└─────────────────────────────────────────────────────────┘
功能:
- 选择设备后显示应用列表
- 创建/删除应用
- 登录/登出应用
- 修改 PIN
- 解锁被锁定的 PIN
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 应用管理 │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择设备 ▼] │
│ │
│ [+ 创建应用] │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 应用名称 登录状态 操作 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ TAGM ● 已登录 [登出][修改PIN][删除]│ │
│ │ TestApp ○ 未登录 [登录][修改PIN][删除]│ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
登录对话框:
┌─────────────────────────────┐
│ 登录应用 │
├─────────────────────────────┤
│ 应用: TAGM │
│ │
│ 角色: ○ 用户 ● 管理员 │
│ │
│ PIN: [********] │
│ │
│ 剩余尝试次数: 3 │
│ │
│ [取消] [登录] │
└─────────────────────────────┘
功能:
- 选择设备和应用后显示容器列表
- 创建/删除容器
- 生成 CSR
- 导入/导出证书
- 验证证书
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 容器管理 │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择 ▼] 应用: [下拉选择 ▼] │
│ │
│ [+ 创建容器] │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 容器名称 密钥类型 密钥状态 证书状态 操作 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ TrustAsia SM2 ● 已生成 ● 已导入 [操作▼]│ │
│ │ Container2 RSA-2048 ○ 未生成 ○ 未导入 [操作▼]│ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 操作菜单: [生成CSR] [导入证书] [导出证书] [验证] [删除] │
└─────────────────────────────────────────────────────────┘
生成 CSR 对话框:
┌─────────────────────────────┐
│ 生成证书请求 (CSR) │
├─────────────────────────────┤
│ 密钥类型: [SM2 ▼] │
│ ○ SM2 (sm2p256v1) │
│ ○ RSA-2048 │
│ ○ RSA-3072 │
│ ○ RSA-4096 │
│ │
│ 通用名 (CN): [___________] │
│ 组织 (O): [___________] │
│ 部门 (OU): [___________] │
│ │
│ □ 重新生成密钥对 (Renew) │
│ │
│ [取消] [生成] │
└─────────────────────────────┘
功能:
- 设置默认应用名、容器名、通用名等
- 切换错误提示模式(简洁/详细)
- 配置 HTTP 监听端口
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 配置管理 │
├─────────────────────────────────────────────────────────┤
│ 默认值设置 │
│ 默认应用名: [TAGM___________] │
│ 默认容器名: [TrustAsia______] │
│ 默认通用名: [TrustAsia______] │
│ 默认组织: [TrustAsia______] │
│ 默认部门: [GMCA___________] │
│ 默认角色: [● 用户 ○ 管理员] │
│ │
│ 系统设置 │
│ HTTP 端口: [9001] │
│ 错误提示: [● 简洁 ○ 详细] │
│ 日志级别: [Info ▼] │
│ │
│ [恢复默认] [保存] │
└─────────────────────────────────────────────────────────┘
功能:
- 实时显示应用日志
- 搜索/过滤日志
- 按级别过滤(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 次 │ │
│ │ ... │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
功能:
- 显示设备应用内的文件列表
- 创建/上传文件到设备
- 读取/下载文件到本地
- 删除文件
界面元素:
┌─────────────────────────────────────────────────────────┐
│ 文件管理 [+ 创建文件] │
├─────────────────────────────────────────────────────────┤
│ 设备: [下拉选择设备 ▼] 应用: [下拉选择应用 ▼] │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 文件名 大小 操作 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 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
- 读取文件时弹出保存对话框,选择本地保存位置
- 删除操作需要二次确认
行为:
- 关闭窗口时最小化到托盘(不退出)
- 托盘图标右键菜单:
- 显示主窗口
- 退出
托盘图标状态:
- 正常状态:标准图标
- 有设备连接时:可选择显示设备数量角标
简洁模式(默认):
┌─────────────────────────────┐
│ ⚠️ 操作失败 │
│ │
│ PIN 错误,剩余 2 次尝试机会 │
│ │
│ [确定] │
└─────────────────────────────┘
详细模式:
┌─────────────────────────────┐
│ ⚠️ 操作失败 │
│ │
│ PIN 错误,剩余 2 次尝试机会 │
│ │
│ 错误码: 0x0A000024 │
│ 函数: SKF_VerifyPIN │
│ 设备: 1234567890 │
│ │
│ [确定] │
└─────────────────────────────┘
- 路径:
~/.wekeytool.json - 格式: JSON
- 编码: UTF-8
{
"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"
}
}| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
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 | 见下 | 默认值配置 |
| 指标 | 目标 |
|---|---|
| 应用启动时间 | < 2 秒 |
| 设备枚举响应 | < 500 毫秒 |
| 签名操作响应 | < 1 秒 |
| 内存占用 | < 100 MB (空闲时) |
- PIN 码在内存中不明文存储
- PIN 输入框使用密码掩码
- 日志中不记录敏感信息(PIN、私钥)
- 通信仅限本地 (localhost)
- 设备热插拔不导致崩溃
- 所有 SKF 调用错误码正确处理
- 句柄泄漏检测(Debug 模式)
- 配置文件向后兼容原 Go 版本
- HTTP API 100% 兼容原 Go 版本
- 分发形式: 绿色版 (Portable)
- 目录结构:
wekey-skf/ ├── wekey-skf.exe # 主程序 ├── Qt6Core.dll # Qt 运行时 ├── Qt6Widgets.dll ├── Qt6Network.dll ├── plugins/ # 驱动插件 │ └── skf.dll └── lib/ # 内嵌厂商库 └── libskf.dll
- 分发形式: DMG 安装包
- 目录结构:
wekey-skf.app/ └── Contents/ ├── MacOS/ │ └── wekey-skf # 主程序 ├── Frameworks/ # Qt 框架 ├── PlugIns/ # 驱动插件 └── Resources/ # 内嵌厂商库 └── lib/ └── libskf.dylib
- 使用
QLockFile或命名互斥量 - 检测到已有实例时:激活现有窗口,退出新实例
- 端口冲突时:弹窗提示,引导用户关闭占用程序或修改端口
| 阶段 | 内容 |
|---|---|
| M1: 基础框架 | 项目结构、构建系统、插件接口定义 |
| M2: SKF 驱动 | SKF 插件实现、C API 封装 |
| M3: 核心功能 | 设备/应用/容器管理、证书操作 |
| M4: HTTP API | REST API 实现、兼容性测试 |
| M5: GUI 实现 | Qt Widgets 界面、系统托盘 |
| M6: 测试与打包 | 集成测试、安装包制作 |
| 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 | 应用不存在 |
| 术语 | 说明 |
|---|---|
| SKF | 智能密码钥匙密码应用接口 (国密标准) |
| SM2 | 国密椭圆曲线公钥密码算法 |
| SM3 | 国密杂凑算法 |
| SM4 | 国密分组密码算法 |
| CSR | Certificate Signing Request (证书签名请求) |
| PIN | Personal Identification Number (个人识别码) |
| 容器 | 密钥对和证书的存储单元 |
| 应用 | 设备内的逻辑分区,包含多个容器 |
文档结束