证书与密钥管理
这一页覆盖「证书与密钥管理」区域的全部操作:导入证书、本地生成密钥与 CSR、查看 / 导出证书、 删除密钥,以及从云端安全下发证书。
| 按钮 | 作用 | 常见格式 |
|---|---|---|
| ➕ 导入PFX | 导入含私钥的证书包(私钥会绑定到卡上密钥容器) | .pfx / .p12 |
| ➕ 创建CSR | 在卡内生成密钥对 + 生成证书请求文件,交 CA 签发 | .csr(附 .inf) |
| ➕ 导入CER | 导入 CA 签发回来的证书(要求卡上已有对应密钥) | .p7b / .cer |
| 🔒 查看信息 | 读取卡上证书与密钥信息,并导出到 %APPDATA% 后打开目录 | — |
| 💾 导出证书 | 导出证书公钥数据(私钥不可导出) | .cer |
| ❌ 删除密钥 | 删除卡上的密钥对象 | — |
证书列表的列:证书编号(GUID)、证书名称、公钥长度、密钥用途。
两条格式限制(界面提示原文)
- PFX:
只能导入 RSA1024/2048 和 SHA1/256 单文件—— 不支持 ECC/SM2 等多算法包、不支持包含多条证书链的包; - CER:
只能导入当前智能卡已存在对应密钥的证书—— 卡上没有对应私钥时导入必然失败。
1. 导入 PFX(把已有私钥装进卡)
选中卡片 → ➕ 导入PFX;
弹出证书导入窗口,填写:
项 说明 证书文件 过滤 .pfx;.p12证书密码 PFX 的导出密码 使用自定义CSP 默认 Microsoft Base Smart Card Crypto Provider;下拉项来自certutil -csplist,一般不用改云端下发 打开后改为「从云端取件」,见本文第 6 节 提交后工具会:把 PFX 写到
%APPDATA%下的临时文件 → 执行certutil -csp "<CSP>" -p <密码> -importpfx <文件>→ 覆写并销毁临时文件;提示「对象或属性已经存在」不是失败(说明证书此前已导入,退出码仍为 0);
导入成功后回到主界面点 🔄 重新加载,证书会出现在「证书与密钥管理」列表里。
导入后证书不显示?
先 certutil -scinfo -silent 看驱动能否打开卡上密钥:
- 报「找不到储存的密钥集」→ 卡上密钥与 PIN 数据在本机解不开(DPAPI 层问题,多见于还原后);
- 能打开密钥但没有证书 → 证书确实没导进去,重做一次导入;
- 证书在但链不完整(
CERT_E_CHAINING)→ 把签发它的中级 CA 证书导入「受信任的中间/根证书」。
2. 创建 CSR(在卡内生成密钥并申请证书)
这是推荐路径:密钥在卡(TPM)内生成,私钥从不出现于磁盘。
选中卡片 → ➕ 创建CSR;
填写申请表(对应
certreq的.inf模板):字段 是否必填 取值 通用名称(CN) 必填(1~64 字符) 例如 zhangsan或域名组织名称 / 组织单元 选填 会进入证书的 Subject 所在地区 / 所在城市 选填 同上 国家代码 选填 下拉选择( Config/cncode.json)加密算法 — RSA1024/RSA2048(默认 2048)摘要算法 — SHA1/SHA256(默认 SHA256)密钥限制 — 「允许签名」「允许解密」(对应 Key Usage 位) 其他特性 — 「邮件加密」 密钥用途 — 数字签名 / 认可签名 / 加密解密 / 密钥协商 / 证书签发 / 仅作加密 / 仅作解密,可多选 域名列表 / 邮箱列表 选填 分号分隔(SAN / 邮箱属性) 自定义 CSP 选填 默认智能卡 CSP 提交后工具先生成
.inf到%APPDATA%,再执行certreq -new -f <inf> <csr>, 并把生成的.csr保存到你选择的位置;把
.csr交给 CA(内部 CA / 公共 CA / 企业证书服务)签发;拿到签发结果(
.cer/.p7b)后回到界面点 ➕ 导入CER —— 工具会把证书与卡上密钥配对 (Import\TPMImport.exe写入用户存储 /certreq -accept接受申请);点 🔄 重新加载 确认证书与密钥用途显示正常。
这是最安全的方式
CA 只见过公钥,私钥自始至终在 TPM 内生成、从未离开。相比之下,"导入 PFX"意味着私钥曾经 以文件形式存在过(需要在别处生成并导出),安全性略低。
3. 导入 CER / P7B
- 用途:卡上已经有了对应密钥(例如刚用 CSR 申请完,或之前导入过 PFX),现在只需把证书装回来;
- 操作:选中卡片 → ➕ 导入CER → 选择
.p7b/.cer文件; - 工具用随包的
Import\TPMImport.exe(.NET 工具,-user -b <文件> <密码>)把它写入用户证书存储, 与卡上密钥配对; - 若卡上没有对应密钥,会导入失败并提示(这是正确行为:证书没有私钥就无法用于签名/解密)。
4. 查看信息与导出证书
| 操作 | 行为 |
|---|---|
| 🔒 查看信息 | 读取卡上密钥与证书详情,导出到 %APPDATA% 并打开资源管理器;只能导出证书公钥数据,私钥被 TPM 加密、无法导出 |
| 💾 导出证书 | 把选中证书导出为证书文件(公钥 + 属性),用于分发给对端(如 SSH 的 authorized_keys、服务端信任列表) |
| ❌ 删除密钥 | 执行 certutil -delkey -csp "Microsoft Base Smart Card Crypto Provider" "<密钥名>";删除后证书失效,且可能需要重启系统才能刷新状态 |
「证书详情 / 使用者 / 颁发者」区域展示的字段:
| 分组 | 字段 |
|---|---|
| 证书详情 | 证书编号、证书名称、密钥类型、摘要类型、生效日期、失效日期、是否为 CA、是否过期、证书 SHA1、密钥用途、拓展用途、密钥标识、证书串号、身份标识、证书策略 |
| 使用者(Subject) | 通用名称、国家代码、所在地区、所在城市、组织名称、部门名称 |
| 颁发者(Issuer) | 同上一组字段 |
5. 证书链不完整(CERT_E_CHAINING)
签发证书的中级 CA 没有装在当前机器上时会出现该提示。处理方式:
- 从 CA 获取中级 CA / 根 CA 证书;
- 导入到「受信任的根证书颁发机构」或「中间证书颁发机构」;
- 重新查看证书链是否完整。
6. 云端安全下发证书(可选)
适合"CA 在服务端、私钥需要送到客户端卡上"的场景。核心设计是密钥材料不经明文网络传输: 服务端用取件码派生密钥加密私钥包,取件码通过带外方式(电话 / 短信 / 另一个渠道)交给使用者。
在「导入PFX」窗口里打开 云端下发 开关后有两种模式:
| 模式 | 流程 |
|---|---|
| 使用密码下发(取件码)(默认) | ① 用取件码向云端 GET /card/get/cert?code=… 取件;② 云端返回 salt / iterations / vaults;③ 本地用 PBKDF2-HMAC-SHA256(取件码, salt, iterations, 32 字节) 派生密钥;④ 用 AES-256-CBC 解密取回的私钥包;⑤ 得到 PFX 后走正常的 PFX 导入流程 |
| 交换密钥 | 本地生成临时 X25519 密钥对,与云端公钥协商出共享密钥后再走同一套 AES-256-CBC 解密 |
- 云端地址可在界面里填写(默认示例地址指向测试 CA,请替换为你自己的服务地址);
- 同机也可运行随包的 Flask 接收端
SmartCardWEB.py(监听0.0.0.0:1080,路由/web/cert、/put/cert、/get/cert,证书缓存写入Caches\PullCerts.pkl),用于自建下发服务或本机联调; - 实现的细节在
Module/Cryptography.py(取件码规范化 + PBKDF2 + AES)与SubApp/CertImport.py(取件与导入流程)。
安全提醒
- 取件码的强度决定私钥包的强度:务必用长随机码,并通过另一个渠道告知使用者;
- 取件完成后请让服务端使取件码失效,避免重复取件;
- 云端下发只支持 PFX 路径,所以请确认拿到的是
RSA1024/2048 + SHA1/256。