Files
npm-tool/.qoder/repowiki/zh/content/核心模块/SM4 算法模块 (TsSM4).md

490 lines
13 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.

# SM4 算法模块 (TsSM4)
<cite>
**本文档引用的文件**
- [TsSM4.js](file://src/utils/TsSM4.js)
- [TsCrypto.js](file://src/utils/TsCrypto.js)
- [TsGlobalConfig.js](file://src/utils/TsGlobalConfig.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. [结论](#结论)
## 简介
SM4 算法模块是基于中国国家密码标准的对称加密算法实现,采用 128 位分组长度和 128 位密钥长度。该模块提供了完整的 SM4 加密解密功能,支持 CBC 和 ECB 两种工作模式,并实现了 PKCS7 自动填充算法。模块设计遵循现代 JavaScript 最佳实践,使用 ES6 类语法和 TypedArray 数据结构,确保高性能和内存效率。
本模块在企业级应用中用于数据加密、安全通信和敏感信息保护,特别适用于需要符合中国国家标准的加密需求场景。
## 项目结构
该项目采用模块化组织方式,主要包含以下核心文件:
```mermaid
graph TB
subgraph "核心模块"
SM4[TsSM4.js<br/>主加密模块]
Crypto[TsCrypto.js<br/>加密服务封装]
Global[TsGlobalConfig.js<br/>全局配置]
end
subgraph "工具模块"
Common[TsCommon.js<br/>通用工具]
Storage[TsStorage.js<br/>存储工具]
HttpUtil[TsHttpUtil.js<br/>HTTP工具]
end
subgraph "入口文件"
Index[index.js<br/>模块导出]
Package[package.json<br/>依赖管理]
end
SM4 --> Crypto
Crypto --> Global
Index --> SM4
Index --> Crypto
Index --> Common
Index --> Storage
Index --> HttpUtil
Package --> SM4
Package --> Crypto
```
**图表来源**
- [TsSM4.js:1-456](file://src/utils/TsSM4.js#L1-L456)
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [index.js:1-16](file://index.js#L1-L16)
**章节来源**
- [TsSM4.js:1-456](file://src/utils/TsSM4.js#L1-L456)
- [index.js:1-16](file://index.js#L1-L16)
## 核心组件
### 主要类结构
TsSM4 模块包含两个核心类Crypt 工具类和 TsSM4 加密类。
```mermaid
classDiagram
class Crypt {
+stringToArrayBufferInUtf8(str) Uint8Array
+utf8ArrayBufferToString(buffer) String
+arrayBufferToBase64(buffer) String
+base64ToArrayBuffer(base64) Uint8Array
}
class TsSM4 {
-Uint8Array key
-Uint8Array iv
-String mode
-String cipherType
-Uint32Array encryptRoundKeys
-Uint32Array decryptRoundKeys
+constructor(config)
+doBlockCrypt(blockData, roundKeys) Uint32Array
+spawnEncryptRoundKeys() Uint32Array
+rotateLeft(x, y) Number
+linearTransform1(b) Number
+linearTransform2(b) Number
+tauTransform(a) Number
+tTransform1(z) Number
+tTransform2(z) Number
+padding(originalBuffer) Uint8Array
+dePadding(paddedBuffer) Uint8Array
+uint8ToUint32Block(uint8Array, baseIndex) Uint32Array
+encrypt(plaintext) String
+decrypt(ciphertext) String
}
class TsCrypto {
-SM4 sm4
+constructor()
+encrypt(content) String
+decrypt(base64) String
}
TsSM4 --> Crypt : "使用"
TsCrypto --> TsSM4 : "封装"
```
**图表来源**
- [TsSM4.js:39-453](file://src/utils/TsSM4.js#L39-L453)
- [TsCrypto.js:5-31](file://src/utils/TsCrypto.js#L5-L31)
### 关键常量定义
模块定义了 SM4 算法的核心常量:
- **Sbox 替换表**: 16×16 的 S 盒替换表,用于字节替换操作
- **CK 常量数组**: 32 个轮常量,用于密钥扩展
- **FK 固定常量**: 4 个固定常量,用于初始密钥处理
**章节来源**
- [TsSM4.js:5-37](file://src/utils/TsSM4.js#L5-L37)
## 架构概览
### 整体架构设计
```mermaid
graph TB
subgraph "应用层"
App[业务应用]
Config[配置管理]
end
subgraph "加密服务层"
CryptoService[TsCrypto]
SM4Engine[TsSM4]
end
subgraph "数据转换层"
Base64[Base64 编码]
UTF8[UTF-8 编码]
ByteArray[字节数组]
end
subgraph "底层实现"
SBox[S 盒表]
RoundKeys[轮密钥]
Transform[变换函数]
end
App --> CryptoService
Config --> CryptoService
CryptoService --> SM4Engine
SM4Engine --> Base64
SM4Engine --> UTF8
SM4Engine --> ByteArray
SM4Engine --> SBox
SM4Engine --> RoundKeys
SM4Engine --> Transform
```
**图表来源**
- [TsSM4.js:96-156](file://src/utils/TsSM4.js#L96-L156)
- [TsCrypto.js:5-31](file://src/utils/TsCrypto.js#L5-L31)
### 数据流处理
```mermaid
sequenceDiagram
participant Client as 应用客户端
participant Crypto as TsCrypto
participant SM4 as TsSM4
participant Crypt as Crypt工具
Client->>Crypto : encrypt(明文)
Crypto->>SM4 : encrypt(明文)
SM4->>Crypt : stringToArrayBufferInUtf8(明文)
Crypt-->>SM4 : UTF-8 字节数组
SM4->>SM4 : padding(填充)
SM4->>SM4 : CBC/ECB 模式处理
SM4->>Crypt : arrayBufferToBase64(密文)
Crypt-->>SM4 : Base64 字符串
SM4-->>Crypto : 密文字符串
Crypto-->>Client : 密文字符串
```
**图表来源**
- [TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
- [TsCrypto.js:19-21](file://src/utils/TsCrypto.js#L19-L21)
## 详细组件分析
### SM4 核心算法实现
#### 密钥扩展算法
密钥扩展是 SM4 算法的核心步骤,负责从原始密钥生成 32 个轮密钥。
```mermaid
flowchart TD
Start([开始密钥扩展]) --> ExtractMK["提取 MK 密钥<br/>mk[0..3] = key[0..15]"]
ExtractMK --> InitK["初始化 K 数组<br/>k[0..3] = mk ⊕ FK"]
InitK --> Loop{"循环 i = 0..31"}
Loop --> CalcK["计算 k[i+4] = k[i] ⊕ T(k[i+1] ⊕ k[i+2] ⊕ k[i+3] ⊕ CK[i])"]
CalcK --> SaveKey["保存轮密钥<br/>encryptRoundKeys[i] = k[i+4]"]
SaveKey --> Loop
Loop --> |完成| ReverseKeys["反转密钥顺序<br/>decryptRoundKeys = reverse(encryptRoundKeys)"]
ReverseKeys --> End([结束])
```
**图表来源**
- [TsSM4.js:189-207](file://src/utils/TsSM4.js#L189-L207)
#### 轮函数实现
每个 SM4 轮包含多个变换操作:
```mermaid
flowchart TD
BlockIn[16字节明文块] --> SplitBlock["分割为4个32位字<br/>block[0..3]"]
SplitBlock --> RoundLoop{"i = 0..31"}
RoundLoop --> XOROp["x[i+4] = x[i] ⊕ T(x[i+1] ⊕ x[i+2] ⊕ x[i+3] ⊕ RK[i])"]
XOROp --> RoundLoop
RoundLoop --> |完成| FinalBlock["组合最终块<br/>y[0..3] = x[32..35]"]
FinalBlock --> BlockOut[16字节密文块]
```
**图表来源**
- [TsSM4.js:166-180](file://src/utils/TsSM4.js#L166-L180)
#### 变换函数详解
##### τ 变换 (字节替换)
τ 变换使用 S 盒进行非线性替换:
- 输入: 32位值
- 处理: 将每个字节通过 S 盒查找替换
- 输出: 32位值
##### L 线性变换
L 变换实现位移和异或操作:
- L1: b ⊕ (b <<< 2) (b <<< 10) (b <<< 18) (b <<< 24)
- L2: b (b <<< 13) (b <<< 23)
##### T 组合变换
T 变换结合 τ L 变换
- T1: L1(τ(z))
- T2: L2(τ(z))
**章节来源**
- [TsSM4.js:250-277](file://src/utils/TsSM4.js#L250-L277)
### 工作模式实现
#### CBC 模式
CBC (Cipher Block Chaining) 模式提供链式加密
```mermaid
sequenceDiagram
participant P as 明文块
participant IV as 初始化向量
participant XOR as 异或运算
participant ENC as 加密器
participant C as 密文块
P1->>XOR : 明文1 ⊕ IV
XOR->>ENC : (明文1 ⊕ IV)
ENC-->>C : 密文1
C->>XOR : 密文1 ⊕ 明文2
XOR->>ENC : (密文1 ⊕ 明文2) ⊕ IV
ENC-->>C : 密文2
Note over IV,C : 每次使用前一个密文作为链输入
```
**图表来源**
- [TsSM4.js:343-378](file://src/utils/TsSM4.js#L343-L378)
#### ECB 模式
ECB (Electronic Codebook) 模式提供独立块加密
```mermaid
flowchart TD
Plain1[明文块1] --> Encrypt1[独立加密]
Plain2[明文块2] --> Encrypt2[独立加密]
Plain3[明文块3] --> Encrypt3[独立加密]
Encrypt1 --> Cipher1[密文块1]
Encrypt2 --> Cipher2[密文块2]
Encrypt3 --> Cipher3[密文块3]
Note1[相同明文块产生相同密文块]
Note2[无链式依赖]
```
**图表来源**
- [TsSM4.js:368-378](file://src/utils/TsSM4.js#L368-L378)
### PKCS7 填充算法
PKCS7 是一种标准的块填充方案
```mermaid
flowchart TD
Start([开始填充]) --> CheckNull{"输入为空?"}
CheckNull --> |是| ReturnNull[返回 null]
CheckNull --> |否| CalcPad["计算填充长度<br/>padLen = 16 - (len % 16)"]
CalcPad --> CreateBuffer["创建新缓冲区<br/>长度 = 原长度 + padLen"]
CreateBuffer --> CopyData["复制原数据到新缓冲区"]
CopyData --> FillPad["填充 padLen 个字节<br/>每个字节值为 padLen"]
FillPad --> ReturnBuffer[返回填充后的缓冲区]
ReturnNull --> End([结束])
ReturnBuffer --> End
```
**图表来源**
- [TsSM4.js:287-296](file://src/utils/TsSM4.js#L287-L296)
**章节来源**
- [TsSM4.js:287-312](file://src/utils/TsSM4.js#L287-L312)
### 数据类型转换
#### 字节数组与 32 位整数转换
```mermaid
flowchart TD
Uint8Array[Uint8Array] --> SplitBytes["按字节分割<br/>每4字节组成一个32位整数"]
SplitBytes --> ShiftLeft["左移操作<br/>高位字节 << 24, 16, 8, 0"]
ShiftLeft --> ORCombine["按位或组合<br/>形成32位整数"]
ORCombine --> Uint32Array[Uint32Array]
Uint32Array --> SplitBits["按位拆分<br/>32位整数拆分为4个字节"]
SplitBits --> ShiftRight["右移操作<br/>高位字节 >> 24, 16, 8, 0"]
ShiftRight --> ANDMask["按位与掩码<br/>& 0xFF"]
ANDMask --> Uint8Array[Uint8Array]
```
**图表来源**
- [TsSM4.js:322-329](file://src/utils/TsSM4.js#L322-L329)
**章节来源**
- [TsSM4.js:322-329](file://src/utils/TsSM4.js#L322-L329)
## 依赖关系分析
### 外部依赖
```mermaid
graph TB
subgraph "外部库"
Base64[base64-js@1.5.1<br/>Base64 编解码]
UmiRequest[umi-request@1.4.0<br/>HTTP 请求]
end
subgraph "内部模块"
SM4[TsSM4.js<br/>SM4 加密算法]
Crypto[TsCrypto.js<br/>加密服务封装]
Global[TsGlobalConfig.js<br/>全局配置]
Common[TsCommon.js<br/>通用工具]
Storage[TsStorage.js<br/>存储工具]
HttpUtil[TsHttpUtil.js<br/>HTTP 工具]
end
SM4 --> Base64
Crypto --> Base64
Crypto --> Global
HttpUtil --> UmiRequest
```
**图表来源**
- [package.json:19-22](file://package.json#L19-L22)
- [TsSM4.js](file://src/utils/TsSM4.js#L1)
- [TsCrypto.js](file://src/utils/TsCrypto.js#L1)
### 内部模块依赖
```mermaid
graph LR
SM4[TsSM4] --> Crypt[Crypt 工具类]
Crypto[TsCrypto] --> SM4
Crypto --> Global[全局配置]
HttpUtil[TsHttpUtil] --> SM4
HttpUtil --> Crypto
```
**图表来源**
- [TsSM4.js:1-94](file://src/utils/TsSM4.js#L1-L94)
- [TsCrypto.js:1-3](file://src/utils/TsCrypto.js#L1-L3)
- [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)
## 性能考虑
### 内存使用分析
#### 数据结构内存占用
| 数据结构 | 大小 | 用途 |
|---------|------|------|
| Uint8Array | 1 字节/元素 | 原始字节数据 |
| Uint32Array | 4 字节/元素 | 32位整数运算 |
| Sbox | 256 字节 | 字节替换表 |
| 轮密钥数组 | 128 字节 | 32个轮密钥 |
| 中间变量 | ~144 字节 | 临时计算结果 |
#### 内存优化策略
1. **TypedArray 使用**: 优先使用 TypedArray 减少内存开销
2. **就地计算**: 尽可能重用数组避免额外分配
3. **批量处理**: 一次处理多个块提高缓存利用率
### 性能特征
#### 时间复杂度
- **密钥扩展**: O(1) - 固定 32 次迭代
- **单块加密**: O(1) - 固定 32 轮运算
- **整体加密**: O(n) - n 为块数量
#### 空间复杂度
- **内存使用**: O(n) - n 为输入数据大小
- **额外开销**: O(1) - 固定大小的中间变量
### 并发处理
模块当前不支持并发操作建议
1. 为每个并发任务创建独立的 TsSM4 实例
2. 避免在多线程环境中共享同一实例
3. 考虑使用 Web Workers 处理大量数据
## 故障排除指南
### 常见错误及解决方案
#### 密钥长度错误
**问题**: 密钥长度不是 16 字节
**解决**: 确保密钥为 16 字节长度
**位置**: [TsSM4.js:103-105](file://src/utils/TsSM4.js#L103-L105)
#### IV 参数错误
**问题**: CBC 模式下 IV 长度不正确
**解决**: 确保 IV 16 字节长度
**位置**: [TsSM4.js:119-121](file://src/utils/TsSM4.js#L119-L121)
#### 填充数据错误
**问题**: 去填充时数据格式不正确
**解决**: 确保使用相同的填充算法进行加解密
**位置**: [TsSM4.js:309-311](file://src/utils/TsSM4.js#L309-L311)
### 调试技巧
1. **启用详细日志**: 在开发环境中输出中间计算结果
2. **单元测试**: 为关键函数编写测试用例
3. **边界测试**: 测试空数据单块数据多块数据等场景
**章节来源**
- [TsSM4.js:103-121](file://src/utils/TsSM4.js#L103-L121)
- [TsSM4.js:309-311](file://src/utils/TsSM4.js#L309-L311)
## 结论
SM4 算法模块提供了完整高效的中国国家标准加密实现模块具有以下特点
### 技术优势
1. **标准兼容**: 完全符合 SM4 算法规范
2. **性能优秀**: 使用 TypedArray 和优化算法
3. **接口友好**: 提供简洁的加密解密接口
4. **模式完整**: 支持 CBC ECB 两种工作模式
### 应用场景
- 企业数据加密
- 网络通信安全
- 敏感信息保护
- 符合国家标准的系统集成
### 发展建议
1. **添加更多模式**: 考虑支持 OFBCFB 等模式
2. **性能优化**: 实现 SIMD 指令集优化
3. **安全性增强**: 添加完整性校验机制
4. **文档完善**: 提供更详细的使用示例
该模块为企业级应用提供了可靠的加密解决方案满足了中国国家标准的要求同时保持了良好的性能和易用性