Files
npm-tool/.qoder/repowiki/zh/content/核心模块/加密模块 (TsCrypto).md

398 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 加密模块 (TsCrypto)
<cite>
**本文引用的文件列表**
- [TsCrypto.js](file://src/utils/TsCrypto.js)
- [TsSM4.js](file://src/utils/TsSM4.js)
- [TsGlobalConfig.js](file://src/utils/TsGlobalConfig.js)
- [TsHttpUtil.js](file://src/https/TsHttpUtil.js)
- [TsStorage.js](file://src/utils/TsStorage.js)
- [index.js](file://index.js)
- [package.json](file://package.json)
- [README.md](file://README.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为加密模块TsCrypto的全面技术文档聚焦于基于 SM4 算法的加密与解密实现,覆盖 CBC 与 ECB 模式支持与配置、Base64 编解码机制、自动填充与去填充算法,以及与全局配置系统、存储系统和 HTTP 请求模块的集成方式。文档同时提供完整的 API 接口说明、使用示例、性能与安全最佳实践并解释加密开关控制、token 加密传输等典型应用场景。
## 项目结构
该工具包采用按功能模块划分的组织方式:
- utils通用工具与加密核心实现
- TsCrypto.js对外暴露的加密模块入口封装 SM4 并与全局配置联动
- TsSM4.jsSM4 算法实现,含填充/去填充、CBC/ECB 模式、Base64 文本编解码
- TsGlobalConfig.js全局配置读取与设置
- TsStorage.js本地存储与加密开关、token 的持久化
- TsCommon.js通用工具函数如 JSON 解析、URL 参数解析等)
- httpsHTTP 请求封装与加密开关集成
- TsHttpUtil.js统一请求处理、参数预处理、加解密与响应解密
- index.js导出模块集合
- package.json依赖声明base64-js、umi-request
```mermaid
graph TB
subgraph "工具包(utils)"
Crypto["TsCrypto.js"]
SM4["TsSM4.js"]
GConf["TsGlobalConfig.js"]
Store["TsStorage.js"]
Common["TsCommon.js"]
end
subgraph "HTTP(https)"
HttpUtil["TsHttpUtil.js"]
end
Index["index.js"]
Package["package.json"]
Crypto --> SM4
Crypto --> GConf
HttpUtil --> Crypto
HttpUtil --> Store
HttpUtil --> GConf
HttpUtil --> Common
Index --> Crypto
Index --> SM4
Index --> GConf
Index --> Store
Index --> HttpUtil
Package --> SM4
Package --> HttpUtil
```
图表来源
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [TsSM4.js:1-456](file://src/utils/TsSM4.js#L1-L456)
- [TsGlobalConfig.js:1-34](file://src/utils/TsGlobalConfig.js#L1-L34)
- [TsStorage.js:1-55](file://src/utils/TsStorage.js#L1-L55)
- [TsHttpUtil.js:1-171](file://src/https/TsHttpUtil.js#L1-L171)
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:1-24](file://package.json#L1-L24)
章节来源
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:1-24](file://package.json#L1-L24)
## 核心组件
- TsCrypto对外加密模块负责初始化 SM4 实例(默认 ECB 模式、Base64 输出),并提供 encrypt/decrypt 方法。
- TsSM4SM4 算法核心,支持 CBC/ECB 模式、Base64/text 输出、自动 PKCS#7 填充与去填充、UTF-8 字符串编解码。
- TsGlobalConfig全局配置读取与合并提供 base64Key、prefix、httpParams、onHttpError 等。
- TsStorage本地存储封装提供用户 token、加密开关等键值存取。
- TsHttpUtilHTTP 请求封装集成加密开关、请求体加密、响应体解密、token 注入等。
章节来源
- [TsCrypto.js:5-34](file://src/utils/TsCrypto.js#L5-L34)
- [TsSM4.js:96-456](file://src/utils/TsSM4.js#L96-L456)
- [TsGlobalConfig.js:1-34](file://src/utils/TsGlobalConfig.js#L1-L34)
- [TsStorage.js:1-55](file://src/utils/TsStorage.js#L1-L55)
- [TsHttpUtil.js:1-171](file://src/https/TsHttpUtil.js#L1-L171)
## 架构总览
加密模块在工具包中的位置与交互如下:
- TsCrypto 初始化时从全局配置读取 base64Key转换为字节后注入 SM4默认模式为 ECB输出为 Base64。
- TsHttpUtil 在发送请求前根据存储的加密开关决定是否对请求体进行加密;收到响应后若标记为加密,则进行解密并尝试 JSON 解析。
- TsStorage 提供加密开关与 token 的持久化,便于跨页面/会话保持状态。
- TsGlobalConfig 提供全局配置(如前缀、附加参数、错误回调)以影响 HTTP 请求行为。
```mermaid
sequenceDiagram
participant Client as "调用方"
participant HttpUtil as "TsHttpUtil"
participant Store as "TsStorage"
participant Crypto as "TsCrypto"
participant SM4 as "TsSM4"
participant Server as "后端服务"
Client->>HttpUtil : "post(url, data)"
HttpUtil->>Store : "getEncryptBody()"
alt "加密开关开启"
HttpUtil->>Crypto : "encrypt(JSON.stringify(data))"
Crypto->>SM4 : "encrypt(UTF-8字节)"
SM4-->>Crypto : "Base64密文"
Crypto-->>HttpUtil : "Base64密文"
HttpUtil->>Server : "POST { encryptData : Base64密文 }"
else "加密开关关闭"
HttpUtil->>Server : "POST data"
end
Server-->>HttpUtil : "响应 { code, data, encrypt? }"
alt "响应标记为加密"
HttpUtil->>Crypto : "decrypt(data)"
Crypto->>SM4 : "decrypt(Base64密文)"
SM4-->>Crypto : "明文字节数组"
Crypto-->>HttpUtil : "明文字符串"
HttpUtil->>HttpUtil : "parseJSON(可选)"
end
HttpUtil-->>Client : "{ data, recordsTotal }"
```
图表来源
- [TsHttpUtil.js:81-123](file://src/https/TsHttpUtil.js#L81-L123)
- [TsCrypto.js:19-30](file://src/utils/TsCrypto.js#L19-L30)
- [TsSM4.js:338-452](file://src/utils/TsSM4.js#L338-L452)
## 详细组件分析
### TsCrypto 组件分析
- 角色定位:对外加密模块,封装 SM4 并与全局配置联动。
- 关键点:
- 构造函数中从全局配置读取 base64Key转换为字节数组后传入 SM4。
- 默认模式为 ECB输出类型为 Base64。
- 对外提供 encrypt/content 与 decrypt/base64 两个方法,分别委托给 SM4 的对应逻辑。
- 适用场景:作为 HTTP 请求层的加密前置,或独立用于数据加密/解密。
```mermaid
classDiagram
class TsCrypto {
+constructor()
+encrypt(content) String
+decrypt(base64) String
}
class TsSM4 {
+constructor(config)
+encrypt(plaintext) String
+decrypt(ciphertext) String
-padding(buffer) Uint8Array
-dePadding(buffer) Uint8Array
-uint8ToUint32Block(arr, idx) Uint32Array
-doBlockCrypt(block, roundKeys) Uint32Array
-spawnEncryptRoundKeys() void
-tTransform1(z) Uint32
-tTransform2(z) Uint32
-linearTransform1(x) Uint32
-linearTransform2(x) Uint32
-rotateLeft(x,y) Uint32
}
class GlobalConfig {
+getConfig() Object
+setConfig(obj) void
}
TsCrypto --> TsSM4 : "组合"
TsCrypto --> GlobalConfig : "读取配置"
```
图表来源
- [TsCrypto.js:5-34](file://src/utils/TsCrypto.js#L5-L34)
- [TsSM4.js:96-456](file://src/utils/TsSM4.js#L96-L456)
- [TsGlobalConfig.js:19-33](file://src/utils/TsGlobalConfig.js#L19-L33)
章节来源
- [TsCrypto.js:5-34](file://src/utils/TsCrypto.js#L5-L34)
### TsSM4 组件分析
- 角色定位SM4 算法实现,支持 CBC/ECB 模式、Base64/text 输出、UTF-8 编解码、PKCS#7 填充/去填充。
- 关键点:
- 支持 CBC/ECB 模式选择,默认 CBCCBC 需要 16 字节 IV否则抛错。
- 输出类型支持 Base64 与 text输入统一为 UTF-8 字节流。
- 填充/去填充:按 16 字节块进行 PKCS#7 填充与去填充。
- 字符串编解码:通过 Crypt 工具类在 UTF-8 与 Base64 之间转换。
- 性能与复杂度:
- 每块 16 字节,循环 32 轮;时间复杂度 O(n),空间复杂度 O(n)。
- 填充/去填充为线性处理,开销较小。
- 安全性:
- CBC 模式下 IV 必须为 16 字节,且建议随机生成;当前实现未内置 IV 生成,需确保传入合法 IV。
- ECB 模式不推荐用于长文本或重复明文场景,易暴露模式特征。
```mermaid
flowchart TD
Start(["开始"]) --> ToUtf8["UTF-8 编码为字节数组"]
ToUtf8 --> Pad["PKCS#7 填充到 16 字节倍数"]
Pad --> Mode{"模式选择"}
Mode --> |CBC| CbcLoop["逐块 CBC 循环<br/>链式 XOR + 轮函数"]
Mode --> |ECB| EcbLoop["逐块 ECB 循环<br/>直接轮函数"]
CbcLoop --> OutSel{"输出类型"}
EcbLoop --> OutSel
OutSel --> |Base64| ToBase64["Base64 编码"]
OutSel --> |text| ToText["UTF-8 解码"]
ToBase64 --> End(["结束"])
ToText --> End
```
图表来源
- [TsSM4.js:287-312](file://src/utils/TsSM4.js#L287-L312)
- [TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
- [TsSM4.js:408-452](file://src/utils/TsSM4.js#L408-L452)
章节来源
- [TsSM4.js:96-456](file://src/utils/TsSM4.js#L96-L456)
### TsGlobalConfig 组件分析
- 角色定位:全局配置中心,提供默认配置与运行时合并。
- 关键点:
- 默认 base64Key、prefix、httpParams、onHttpError 等。
- getConfig 返回 window.httpConfig 或默认配置setConfig 合并传入对象。
- 与加密模块的关系:
- TsCrypto 通过 getConfig().base64Key 读取密钥TsHttpUtil 通过 getConfig().prefix/httpParams/onHttpError 影响请求行为。
章节来源
- [TsGlobalConfig.js:1-34](file://src/utils/TsGlobalConfig.js#L1-L34)
- [TsCrypto.js:8-12](file://src/utils/TsCrypto.js#L8-L12)
- [TsHttpUtil.js:100-106](file://src/https/TsHttpUtil.js#L100-L106)
### TsStorage 组件分析
- 角色定位:本地存储封装,提供 token 与加密开关的持久化。
- 关键点:
- save/get统一 JSON 序列化/反序列化。
- saveUserToken/getUserTokentoken 的便捷存取。
- saveEncryptBody/getEncryptBody加密开关的持久化影响 HTTP 请求是否加密请求体。
章节来源
- [TsStorage.js:1-55](file://src/utils/TsStorage.js#L1-L55)
- [TsHttpUtil.js:82-86](file://src/https/TsHttpUtil.js#L82-L86)
### TsHttpUtil 组件分析
- 角色定位HTTP 请求封装集成加密开关、请求体加密、响应体解密、token 注入。
- 关键点:
- dealParamsBody对 GET 参数与 POST 数据进行预处理;当加密开关开启时,将 data 包装为 { encryptData: TsCrypto.encrypt(JSON.stringify(data)) }。
- req发起请求自动拼接 prefix、注入 token、处理响应若响应标记为加密则调用 TsCrypto.decrypt 并尝试 JSON 解析。
- 错误处理:根据状态码映射错误信息,或调用全局 onHttpError 回调。
- 与加密模块的协作:
- 使用 TsCrypto.encrypt/decrypt 完成请求体与响应体的加解密。
- 通过 TsStorage 控制加密开关,通过 TsGlobalConfig 控制前缀与附加参数。
章节来源
- [TsHttpUtil.js:50-91](file://src/https/TsHttpUtil.js#L50-L91)
- [TsHttpUtil.js:99-134](file://src/https/TsHttpUtil.js#L99-L134)
## 依赖关系分析
- TsCrypto 依赖 TsSM4 与 TsGlobalConfig。
- TsHttpUtil 依赖 TsCrypto、TsStorage、TsGlobalConfig、TsCommon。
- TsSM4 依赖 base64-js用于 Base64 编解码)。
- index.js 将各模块统一导出,供外部使用。
- package.json 声明 base64-js 与 umi-request 依赖。
```mermaid
graph LR
TsCrypto["TsCrypto.js"] --> TsSM4["TsSM4.js"]
TsCrypto --> TsGlobalConfig["TsGlobalConfig.js"]
TsHttpUtil["TsHttpUtil.js"] --> TsCrypto
TsHttpUtil --> TsStorage["TsStorage.js"]
TsHttpUtil --> TsGlobalConfig
TsHttpUtil --> TsCommon["TsCommon.js"]
TsSM4 --> Base64["base64-js(依赖)"]
index_js["index.js"] --> TsCrypto
index_js --> TsSM4
index_js --> TsGlobalConfig
index_js --> TsStorage
index_js --> TsHttpUtil
package_json["package.json"] --> Base64
package_json --> UmiReq["umi-request(依赖)"]
```
图表来源
- [TsCrypto.js:1-3](file://src/utils/TsCrypto.js#L1-L3)
- [TsSM4.js:1](file://src/utils/TsSM4.js#L1)
- [TsHttpUtil.js:1-5](file://src/https/TsHttpUtil.js#L1-L5)
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:19-22](file://package.json#L19-L22)
章节来源
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:19-22](file://package.json#L19-L22)
## 性能考量
- 时间复杂度SM4 每块 16 字节32 轮,整体 O(n);填充/去填充为线性处理,开销较小。
- 内存占用:主要为输入/输出字节数组与中间块数组,空间复杂度 O(n)。
- Base64 编解码:在浏览器与 Node 环境均可用 base64-js性能稳定。
- CBC/ECB 选择CBC 增加链式处理但无额外显著性能损耗ECB 更简单但安全性较低。
- 建议:
- 对大文本分块处理(当前实现按块处理,已具备良好扩展性)。
- 在浏览器端避免频繁重复加密,必要时缓存结果。
- 使用 CBC 模式并确保 IV 正确(当前实现要求 16 字节 IV否则抛错
## 故障排查指南
- “iv 错误”异常
- 现象CBC 模式下抛出 iv 错误。
- 原因:未正确传入 16 字节 IV 或未传入 IV。
- 处理:确保传入长度为 16 的 IV或切换至 ECB 模式。
- 参考路径:[TsSM4.js:345-347](file://src/utils/TsSM4.js#L345-L347)、[TsSM4.js:410-412](file://src/utils/TsSM4.js#L410-L412)
- “密钥长度不为 16 字节”
- 现象:构造 SM4 实例时抛出密钥长度错误。
- 原因base64Key 解码后不是 16 字节。
- 处理:确认 base64Key 来自后端并符合规范。
- 参考路径:[TsSM4.js:103-105](file://src/utils/TsSM4.js#L103-L105)
- “响应未解密”
- 现象:响应未按预期解密。
- 原因:响应未标记为加密或密钥不一致。
- 处理:确认后端响应标记 encrypt 且密钥一致。
- 参考路径:[TsHttpUtil.js:119-122](file://src/https/TsHttpUtil.js#L119-L122)
- “加密开关无效”
- 现象:请求未加密。
- 原因:加密开关未启用或未持久化。
- 处理:调用 saveEncryptBody(true) 并确认存储生效。
- 参考路径:[TsStorage.js:17-23](file://src/utils/TsStorage.js#L17-L23)、[TsHttpUtil.js:82-86](file://src/https/TsHttpUtil.js#L82-L86)
章节来源
- [TsSM4.js:103-105](file://src/utils/TsSM4.js#L103-L105)
- [TsSM4.js:345-347](file://src/utils/TsSM4.js#L345-L347)
- [TsSM4.js:410-412](file://src/utils/TsSM4.js#L410-L412)
- [TsHttpUtil.js:119-122](file://src/https/TsHttpUtil.js#L119-L122)
- [TsStorage.js:17-23](file://src/utils/TsStorage.js#L17-L23)
## 结论
本加密模块以 TsCrypto 为核心,结合 TsSM4 的 SM4 算法实现,提供了 CBC/ECB 模式、Base64 编解码、PKCS#7 填充与去填充、UTF-8 字符串编解码能力并与全局配置系统、存储系统、HTTP 请求模块形成完整闭环。通过加密开关与 token 注入,满足了请求体加密与安全传输的常见需求。建议在生产环境中优先使用 CBC 模式并妥善管理 IV 与密钥,遵循最小暴露原则与安全最佳实践。
## 附录
### API 接口文档
- TsCrypto.encrypt(content)
- 功能:对明文字符串进行加密,返回 Base64 字符串。
- 输入:明文字符串。
- 输出Base64 密文字符串。
- 参考路径:[TsCrypto.js:19-21](file://src/utils/TsCrypto.js#L19-L21)、[TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
- TsCrypto.decrypt(base64)
- 功能:对 Base64 密文进行解密,返回明文字符串。
- 输入Base64 密文字符串。
- 输出:明文字符串。
- 参考路径:[TsCrypto.js:28-30](file://src/utils/TsCrypto.js#L28-L30)、[TsSM4.js:395-452](file://src/utils/TsSM4.js#L395-L452)
- TsSM4.encrypt(plaintext)
- 功能:支持 CBC/ECB 模式、Base64/text 输出、UTF-8 编解码与 PKCS#7 填充。
- 输入:明文字符串。
- 输出Base64 或 UTF-8 字符串(取决于 cipherType
- 参考路径:[TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
- TsSM4.decrypt(ciphertext)
- 功能:支持 CBC/ECB 模式、Base64/text 输入、UTF-8 编解码与 PKCS#7 去填充。
- 输入Base64 或 UTF-8 密文字符串。
- 输出:明文字符串。
- 参考路径:[TsSM4.js:395-452](file://src/utils/TsSM4.js#L395-L452)
- TsGlobalConfig.getConfig()/setConfig(obj)
- 功能:读取/设置全局配置,包括 base64Key、prefix、httpParams、onHttpError。
- 参考路径:[TsGlobalConfig.js:19-33](file://src/utils/TsGlobalConfig.js#L19-L33)
- TsStorage.saveEncryptBody(bool)/getEncryptBody()
- 功能:设置/获取加密开关,影响 HTTP 请求是否加密请求体。
- 参考路径:[TsStorage.js:17-23](file://src/utils/TsStorage.js#L17-L23)
- TsHttpUtil.post/get/form(req)
- 功能:统一发起 HTTP 请求自动处理加密开关、请求体加密、响应体解密、token 注入。
- 参考路径:[TsHttpUtil.js:152-165](file://src/https/TsHttpUtil.js#L152-L165)
### 使用示例
- 启用请求体加密
- 设置加密开关:调用 saveEncryptBody(true)。
- 发送请求post(url, data) 自动将 data 包装为 { encryptData: TsCrypto.encrypt(JSON.stringify(data)) }。
- 参考路径:[TsStorage.js:17-23](file://src/utils/TsStorage.js#L17-L23)、[TsHttpUtil.js:82-86](file://src/https/TsHttpUtil.js#L82-L86)
- 响应体解密
- 若后端响应标记为加密,则自动调用 TsCrypto.decrypt 并尝试 JSON 解析。
- 参考路径:[TsHttpUtil.js:119-122](file://src/https/TsHttpUtil.js#L119-L122)
- 自定义密钥与前缀
- 通过 setConfig({ base64Key, prefix }) 配置密钥与请求前缀。
- 参考路径:[TsGlobalConfig.js:27-29](file://src/utils/TsGlobalConfig.js#L27-L29)、[TsHttpUtil.js:100-106](file://src/https/TsHttpUtil.js#L100-L106)
### 安全最佳实践
- CBC 模式
- 使用 16 字节 IV建议随机生成并随消息传输或在协议中约定。
- 避免重复使用相同的 IV 与密钥组合。
- ECB 模式
- 不适用于长文本或存在重复明文的场景,易泄露模式特征。
- 密钥管理
- base64Key 应来自可信后端,定期轮换;避免硬编码在前端。
- 响应校验
- 对响应进行完整性校验(如 HMAC防止篡改。
- 日志与调试
- 生产环境避免打印密文与敏感信息;仅在开发环境启用严格日志级别。