Skip to content

Conversation

@ferstar
Copy link

@ferstar ferstar commented Oct 18, 2025

📋 概述

本 PR 对 GmSSL-Python 进行了全面改进,主要包括:跨平台兼容性修复、自包含动态库支持、代码质量提升、API 优化以及大幅增强的测试覆盖率。这些改进使得 GmSSL-Python 更加健壮、易用,并且可以开箱即用。

✨ 主要改进

1. 🎁 自包含跨平台动态库支持

问题背景

  • 用户需要手动编译安装 GmSSL 库才能使用 gmssl-python
  • 不同平台的安装步骤复杂,对新手不友好
  • 缺少对 ARM64 架构的支持

解决方案

  • ✅ 在包内打包预编译的 GmSSL 动态库(位于 src/gmssl/_libs/
  • ✅ 支持 4 个主流平台:
    • Linux x86_64 (GLIBC 2.17+)
    • Linux aarch64 (ARM64)
    • macOS Universal Binary (Intel + Apple Silicon)
    • Windows x86_64

智能库加载策略

# 优先级顺序(遵循 "Never break userspace" 原则)
1. 系统已安装的 GmSSL  /usr/local/lib/libgmssl.so2. 包内打包的库如果系统库不存在或版本过低3. 版本检查系统库 < 3.1.1 时自动回退到包内库

用户体验提升

  • 🚀 新用户:pip install gmssl-python 即可直接使用,无需额外安装
  • 🔧 高级用户:仍可通过安装系统 GmSSL 覆盖包内库
  • 📦 包大小:约 4-5 MB(已优化,strip 调试符号)

2. 🔧 跨平台兼容性修复

Windows 平台修复

  • 问题:Windows 下 FILE* 指针跨 DLL 边界传递导致崩溃
  • 解决:实现 Windows 专用的 PEM 文件包装器,使用文件路径而非 FILE* 指针
  • 影响:修复 SM2/SM9 的所有 PEM 导入/导出操作
  • 相关提交
    • 004d60a - 解决 FILE* 跨 DLL 边界问题
    • 9af3697 - 添加 Windows 兼容的 PEM 工具
    • 7a293bd, bd84323 - 修复指针类型处理

macOS 平台修复

  • 问题:SM9 PEM 导入时缓冲区未刷新导致数据丢失
  • 解决:在关闭文件前显式调用 fflush()
  • 相关提交7e734cb

Linux ARM64 支持

  • 新增:完整的 aarch64 架构支持
  • 相关提交4734f50, 324af04

3. 📈 测试覆盖率大幅提升

测试数量:从 19 个增加到 124 个(增长 552%)

新增测试套件

  • 错误处理测试 (34 个) - tests/test_errors.py
    • 无效参数、空值、类型错误等
  • 边界条件测试 (28 个) - tests/test_edge_cases.py
    • 最大/最小长度、空数据、特殊字符等
  • 补充方法测试 (15 个) - tests/test_additional_methods.py
    • SM4 decrypt()、SM9 覆盖率提升等
  • 性能和压力测试 (13 个) - tests/test_pygmssl_missing.py
    • 大数据量、多次调用、内存泄漏检测
  • 线程安全测试 (10 个) - tests/test_thread_safety.py
    • 多线程并发测试、竞态条件检测

代码覆盖率

  • 总体覆盖率:77%
  • SM9 模块:从 80% 提升到 86%
  • 配置 pytest-cov 排除平台特定代码

测试通过率100% (124/124)

4. 🎨 代码质量提升

重构 1:引入 _GmsslProxy

问题:大量重复的错误处理代码

# 之前:冗长的错误处理
raise_on_error(gmssl.sm4_cbc_encrypt_init(byref(self), key, iv), "sm4_cbc_encrypt_init")

改进:使用代理模式自动检查错误

# 之后:简洁清晰
checked.sm4_cbc_encrypt_init(byref(self), key, iv)

效果:减少约 136 行样板代码
相关提交1b99b31

重构 2:消除 PEM 工具函数重复

问题:4 个 PEM 函数有 ~80 行重复代码
解决:提取通用逻辑到 _call_platform_pem_function()
效果

  • 减少约 80 行重复代码
  • 提高可维护性
  • 统一错误处理
    相关提交1d4df87

其他改进

  • 添加 pre-commit 配置(ruff 格式化和检查)
  • 修复 ctypes 结构体定义(SM2_KEY, Sm4Gcm)
  • 统一代码风格

5. 🚀 API 改进

新增 Sm4.decrypt() 方法

问题:之前加密和解密都使用 encrypt() 方法,语义不清晰

# 之前:令人困惑
sm4_dec = Sm4(key, DO_DECRYPT)
plaintext = sm4_dec.encrypt(ciphertext)  # 用 encrypt 解密?

改进:添加专用的 decrypt() 方法

# 之后:清晰明了
sm4_dec = Sm4(key, DO_DECRYPT)
plaintext = sm4_dec.decrypt(ciphertext)  # 语义清晰

特性

  • ✅ 运行时验证:在加密模式调用 decrypt() 会抛出异常
  • ✅ 向后兼容:保留 encrypt() 方法
  • ✅ 完整测试覆盖

相关提交cf9b059

6. 📚 文档和线程安全说明

线程安全警告

  • 在 README 中明确说明 Sm4Gcm 不是线程安全的
  • 提供多线程使用的锁保护示例
  • 其他算法(SM2, SM3, SM4-CBC/CTR, SM9, ZUC)均为线程安全

文档更新

  • 更新安装说明(包含自包含库信息)
  • 添加库加载优先级说明
  • 更新测试运行指南

7. 🔄 库更新和构建优化

  • 更新打包的 GmSSL 库到 master 分支
  • 优化 GitHub Actions 工作流
    • 添加平台选择选项
    • 改进符号验证
    • 自动化测试和发布
  • 使用 Release 模式编译以优化性能

🧪 测试证明

所有改进均通过完整测试验证:

$ pytest tests/ -v
================================================= test session starts =================================================
platform linux -- Python 3.12.9, pytest-8.4.2, pluggy-1.6.0
collected 124 items

tests/test_gmssl.py::TestVersion::test_library_version_num PASSED                                              [  0%]
tests/test_gmssl.py::TestVersion::test_library_version_string PASSED                                           [  1%]
...
tests/test_thread_safety.py::TestThreadSafety::test_zuc_thread_safety PASSED                                  [100%]

================================================ 124 passed in 2.34s =================================================

覆盖率报告

$ pytest tests/ --cov=src/gmssl --cov-report=term-missing
---------- coverage: platform linux, python 3.12.9 -----------
Name                          Stmts   Miss  Cover   Missing
-----------------------------------------------------------
src/gmssl/__init__.py            45      0   100%
src/gmssl/_lib.py               156     28    82%
src/gmssl/_pem_utils.py         142     35    75%
src/gmssl/_sm2.py               187     42    78%
src/gmssl/_sm3.py                45      8    82%
src/gmssl/_sm4.py               198     45    77%
src/gmssl/_sm9.py               245     35    86%
src/gmssl/_zuc.py                32      7    78%
-----------------------------------------------------------
TOTAL                          1050    200    77%

✅ 向后兼容性

  • ✅ 所有现有 API 保持不变
  • ✅ 新增的 Sm4.decrypt() 是可选的,不影响现有代码
  • ✅ 库加载策略优先使用系统库,不破坏现有用户环境
  • ✅ 所有原有测试通过

📦 影响范围

受益用户

  • 🆕 新用户:开箱即用,无需手动安装 GmSSL
  • 🪟 Windows 用户:PEM 操作不再崩溃
  • 🍎 macOS 用户:SM9 PEM 导入正常工作
  • 💪 ARM64 用户:原生支持 aarch64 架构
  • 👨‍💻 开发者:更清晰的 API、更好的测试覆盖

包大小变化

  • 增加约 4-5 MB(打包的动态库)
  • 已通过 strip 优化,移除调试符号

🔗 相关 Issue

#4 #8 #9 #12 #16 #20 #21

📝 Checklist

  • 所有测试通过(124/124)
  • 代码覆盖率 ≥ 75%
  • 代码格式化(ruff format)
  • 代码检查通过(ruff check)
  • 向后兼容
  • 文档已更新
  • 跨平台测试(Linux x64/ARM64, macOS, Windows)

🙏 致谢

感谢 GmSSL 项目提供优秀的国密算法实现!

…braries, code quality, and extensive test coverage

## Major Improvements

### 1. Bundled Cross-Platform Libraries
- Add pre-compiled GmSSL libraries in src/gmssl/_libs/
- Support 4 platforms: Linux x64/ARM64, macOS Universal, Windows x64
- Smart library loading: system library first, bundled library as fallback
- Enable pip install gmssl-python to work out-of-the-box

### 2. Cross-Platform Compatibility Fixes
- Fix Windows FILE* cross-DLL boundary issue with elegant wrapper
- Fix macOS SM9 PEM import buffer flush issue
- Add complete Linux aarch64 (ARM64) support
- Fix all SM2/SM9 PEM import/export operations on Windows

### 3. Test Coverage Enhancement (552% increase)
- Add 105 new tests (from 19 to 124 tests)
- Error handling tests (34 tests)
- Edge case tests (28 tests)
- Additional method tests (15 tests)
- Performance and stress tests (13 tests)
- Thread safety tests (10 tests)
- Overall coverage: 77%, SM9 module: 86%

### 4. Code Quality Improvements
- Introduce _GmsslProxy class to reduce 136 lines of boilerplate
- Refactor PEM utilities to eliminate 80 lines of duplication
- Add pre-commit configuration (ruff format and check)
- Fix ctypes structure definitions (SM2_KEY, Sm4Gcm)

### 5. API Enhancements
- Add Sm4.decrypt() method for better API clarity
- Runtime validation to prevent misuse
- Maintain backward compatibility

### 6. Documentation Updates
- Add thread safety warnings for Sm4Gcm
- Update installation guide with bundled library info
- Add library loading priority documentation
- Update test running guide

### 7. Build and CI Optimization
- Update bundled GmSSL libraries to master branch
- Optimize GitHub Actions workflows
- Add platform selection options
- Use Release mode for better performance

All 124 tests passing. Backward compatible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant