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

18 KiB
Raw Blame History

加密模块 (TsCrypto)

**本文引用的文件列表** - [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)

目录

  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
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对外加密模块负责初始化 SM4 实例(默认 ECB 模式、Base64 输出),并提供 encrypt/decrypt 方法。
  • TsSM4SM4 算法核心,支持 CBC/ECB 模式、Base64/text 输出、自动 PKCS#7 填充与去填充、UTF-8 字符串编解码。
  • TsGlobalConfig全局配置读取与合并提供 base64Key、prefix、httpParams、onHttpError 等。
  • TsStorage本地存储封装提供用户 token、加密开关等键值存取。
  • TsHttpUtilHTTP 请求封装集成加密开关、请求体加密、响应体解密、token 注入等。

章节来源

架构总览

加密模块在工具包中的位置与交互如下:

  • TsCrypto 初始化时从全局配置读取 base64Key转换为字节后注入 SM4默认模式为 ECB输出为 Base64。
  • TsHttpUtil 在发送请求前根据存储的加密开关决定是否对请求体进行加密;收到响应后若标记为加密,则进行解密并尝试 JSON 解析。
  • TsStorage 提供加密开关与 token 的持久化,便于跨页面/会话保持状态。
  • TsGlobalConfig 提供全局配置(如前缀、附加参数、错误回调)以影响 HTTP 请求行为。
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 }"

图表来源

详细组件分析

TsCrypto 组件分析

  • 角色定位:对外加密模块,封装 SM4 并与全局配置联动。
  • 关键点:
    • 构造函数中从全局配置读取 base64Key转换为字节数组后传入 SM4。
    • 默认模式为 ECB输出类型为 Base64。
    • 对外提供 encrypt/content 与 decrypt/base64 两个方法,分别委托给 SM4 的对应逻辑。
  • 适用场景:作为 HTTP 请求层的加密前置,或独立用于数据加密/解密。
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 : "读取配置"

图表来源

章节来源

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 模式不推荐用于长文本或重复明文场景,易暴露模式特征。
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

图表来源

章节来源

TsGlobalConfig 组件分析

  • 角色定位:全局配置中心,提供默认配置与运行时合并。
  • 关键点:
    • 默认 base64Key、prefix、httpParams、onHttpError 等。
    • getConfig 返回 window.httpConfig 或默认配置setConfig 合并传入对象。
  • 与加密模块的关系:
    • TsCrypto 通过 getConfig().base64Key 读取密钥TsHttpUtil 通过 getConfig().prefix/httpParams/onHttpError 影响请求行为。

章节来源

TsStorage 组件分析

  • 角色定位:本地存储封装,提供 token 与加密开关的持久化。
  • 关键点:
    • save/get统一 JSON 序列化/反序列化。
    • saveUserToken/getUserTokentoken 的便捷存取。
    • saveEncryptBody/getEncryptBody加密开关的持久化影响 HTTP 请求是否加密请求体。

章节来源

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 控制前缀与附加参数。

章节来源

依赖关系分析

  • TsCrypto 依赖 TsSM4 与 TsGlobalConfig。
  • TsHttpUtil 依赖 TsCrypto、TsStorage、TsGlobalConfig、TsCommon。
  • TsSM4 依赖 base64-js用于 Base64 编解码)。
  • index.js 将各模块统一导出,供外部使用。
  • package.json 声明 base64-js 与 umi-request 依赖。
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(依赖)"]

图表来源

章节来源

性能考量

  • 时间复杂度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-347TsSM4.js:410-412
  • “密钥长度不为 16 字节”
    • 现象:构造 SM4 实例时抛出密钥长度错误。
    • 原因base64Key 解码后不是 16 字节。
    • 处理:确认 base64Key 来自后端并符合规范。
    • 参考路径:TsSM4.js:103-105
  • “响应未解密”
    • 现象:响应未按预期解密。
    • 原因:响应未标记为加密或密钥不一致。
    • 处理:确认后端响应标记 encrypt 且密钥一致。
    • 参考路径:TsHttpUtil.js:119-122
  • “加密开关无效”
    • 现象:请求未加密。
    • 原因:加密开关未启用或未持久化。
    • 处理:调用 saveEncryptBody(true) 并确认存储生效。
    • 参考路径:TsStorage.js:17-23TsHttpUtil.js:82-86

章节来源

结论

本加密模块以 TsCrypto 为核心,结合 TsSM4 的 SM4 算法实现,提供了 CBC/ECB 模式、Base64 编解码、PKCS#7 填充与去填充、UTF-8 字符串编解码能力并与全局配置系统、存储系统、HTTP 请求模块形成完整闭环。通过加密开关与 token 注入,满足了请求体加密与安全传输的常见需求。建议在生产环境中优先使用 CBC 模式并妥善管理 IV 与密钥,遵循最小暴露原则与安全最佳实践。

附录

API 接口文档

  • TsCrypto.encrypt(content)
    • 功能:对明文字符串进行加密,返回 Base64 字符串。
    • 输入:明文字符串。
    • 输出Base64 密文字符串。
    • 参考路径:TsCrypto.js:19-21TsSM4.js:338-387
  • TsCrypto.decrypt(base64)
    • 功能:对 Base64 密文进行解密,返回明文字符串。
    • 输入Base64 密文字符串。
    • 输出:明文字符串。
    • 参考路径:TsCrypto.js:28-30TsSM4.js:395-452
  • TsSM4.encrypt(plaintext)
    • 功能:支持 CBC/ECB 模式、Base64/text 输出、UTF-8 编解码与 PKCS#7 填充。
    • 输入:明文字符串。
    • 输出Base64 或 UTF-8 字符串(取决于 cipherType
    • 参考路径:TsSM4.js:338-387
  • TsSM4.decrypt(ciphertext)
    • 功能:支持 CBC/ECB 模式、Base64/text 输入、UTF-8 编解码与 PKCS#7 去填充。
    • 输入Base64 或 UTF-8 密文字符串。
    • 输出:明文字符串。
    • 参考路径:TsSM4.js:395-452
  • TsGlobalConfig.getConfig()/setConfig(obj)
    • 功能:读取/设置全局配置,包括 base64Key、prefix、httpParams、onHttpError。
    • 参考路径:TsGlobalConfig.js:19-33
  • TsStorage.saveEncryptBody(bool)/getEncryptBody()
    • 功能:设置/获取加密开关,影响 HTTP 请求是否加密请求体。
    • 参考路径:TsStorage.js:17-23
  • TsHttpUtil.post/get/form(req)
    • 功能:统一发起 HTTP 请求自动处理加密开关、请求体加密、响应体解密、token 注入。
    • 参考路径:TsHttpUtil.js:152-165

使用示例

  • 启用请求体加密
    • 设置加密开关:调用 saveEncryptBody(true)。
    • 发送请求post(url, data) 自动将 data 包装为 { encryptData: TsCrypto.encrypt(JSON.stringify(data)) }。
    • 参考路径:TsStorage.js:17-23TsHttpUtil.js:82-86
  • 响应体解密
    • 若后端响应标记为加密,则自动调用 TsCrypto.decrypt 并尝试 JSON 解析。
    • 参考路径:TsHttpUtil.js:119-122
  • 自定义密钥与前缀

安全最佳实践

  • CBC 模式
    • 使用 16 字节 IV建议随机生成并随消息传输或在协议中约定。
    • 避免重复使用相同的 IV 与密钥组合。
  • ECB 模式
    • 不适用于长文本或存在重复明文的场景,易泄露模式特征。
  • 密钥管理
    • base64Key 应来自可信后端,定期轮换;避免硬编码在前端。
  • 响应校验
    • 对响应进行完整性校验(如 HMAC防止篡改。
  • 日志与调试
    • 生产环境避免打印密文与敏感信息;仅在开发环境启用严格日志级别。