当前位置: 首页 > java >正文

Python gmssl.SM4使用案例

Python gmssl.SM4使用案例

一、Python脚本实现(使用gmssl)

python/sm4_crypto_gmssl.py

#!/usr/bin/env python3
import sys
import json
from gmssl import sm4class SM4CryptoGmSSL:def __init__(self):self.sm4_crypt = sm4.CryptSM4()def encrypt(self, key_hex, iv_hex, plaintext_hex):"""SM4 CBC模式加密参数:key_hex: 128位密钥(32个hex字符)iv_hex: 128位初始化向量(32个hex字符)plaintext_hex: 128位明文(32个hex字符)返回:密文的hex字符串"""# 转换hex字符串为字节key = bytes.fromhex(key_hex)iv = bytes.fromhex(iv_hex)plaintext = bytes.fromhex(plaintext_hex)# 设置密钥和模式self.sm4_crypt.set_key(key, sm4.SM4_ENCRYPT)# CBC模式加密ciphertext = self.sm4_crypt.crypt_cbc(iv, plaintext)return ciphertext.hex()def decrypt(self, key_hex, iv_hex, ciphertext_hex):"""SM4 CBC模式解密参数:key_hex: 128位密钥(32个hex字符)iv_hex: 128位初始化向量(32个hex字符)ciphertext_hex: 128位密文(32个hex字符)返回:明文的hex字符串"""# 转换hex字符串为字节key = bytes.fromhex(key_hex)iv = bytes.fromhex(iv_hex)ciphertext = bytes.fromhex(ciphertext_hex)# 设置密钥和模式self.sm4_crypt.set_key(key, sm4.SM4_DECRYPT)# CBC模式解密plaintext = self.sm4_crypt.crypt_cbc(iv, ciphertext)return plaintext.hex()def encrypt_ecb(self, key_hex, plaintext_hex):"""SM4 ECB模式加密(无需IV)"""key = bytes.fromhex(key_hex)plaintext = bytes.fromhex(plaintext_hex)self.sm4_crypt.set_key(key, sm4.SM4_ENCRYPT)ciphertext = self.sm4_crypt.crypt_ecb(plaintext)return ciphertext.hex()def validate_hex_string(hex_str, expected_length):"""验证十六进制字符串的有效性和长度"""try:bytes.fromhex(hex_str)if len(hex_str) != expected_length:raise ValueError(f"Expected {expected_length} hex characters, got {len(hex_str)}")return Trueexcept ValueError as e:return Falsedef main():"""主函数,处理命令行参数"""if len(sys.argv) < 2:result = {"status": "error","message": "Usage: python sm4_crypto_gmssl.py <command> [args...]"}print(json.dumps(result))sys.exit(1)sm4_crypto = SM4CryptoGmSSL()command = sys.argv[1]if command == "encrypt":if len(sys.argv) != 5:result = {"status": "error","message": "Usage: python sm4_crypto_gmssl.py encrypt <key> <iv> <plaintext>"}print(json.dumps(result))sys.exit(1)key = sys.argv[2]iv = sys.argv[3]plaintext = sys.argv[4]# 验证输入if not validate_hex_string(key, 32):result = {"status": "error", "message": "Invalid key format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)if not validate_hex_string(iv, 32):result = {"status": "error", "message": "Invalid IV format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)if not validate_hex_string(plaintext, 32):result = {"status": "error", "message": "Invalid plaintext format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)try:ciphertext = sm4_crypto.encrypt(key, iv, plaintext)result = {"status": "success","operation": "encrypt","key": key,"iv": iv,"plaintext": plaintext,"ciphertext": ciphertext}except Exception as e:result = {"status": "error","message": f"Encryption failed: {str(e)}"}print(json.dumps(result))elif command == "decrypt":if len(sys.argv) != 5:result = {"status": "error","message": "Usage: python sm4_crypto_gmssl.py decrypt <key> <iv> <ciphertext>"}print(json.dumps(result))sys.exit(1)key = sys.argv[2]iv = sys.argv[3]ciphertext = sys.argv[4]# 验证输入if not validate_hex_string(key, 32):result = {"status": "error", "message": "Invalid key format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)if not validate_hex_string(iv, 32):result = {"status": "error", "message": "Invalid IV format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)if not validate_hex_string(ciphertext, 32):result = {"status": "error", "message": "Invalid ciphertext format (need 32 hex chars)"}print(json.dumps(result))sys.exit(1)try:plaintext = sm4_crypto.decrypt(key, iv, ciphertext)result = {"status": "success","operation": "decrypt","key": key,"iv": iv,"ciphertext": ciphertext,"plaintext": plaintext}except Exception as e:result = {"status": "error","message": f"Decryption failed: {str(e)}"}print(json.dumps(result))elif command == "test":# 内置测试命令test_key = "0123456789abcdef0123456789abcdef"test_iv = "fedcba9876543210fedcba9876543210"test_plaintext = "48656c6c6f20576f726c6421212121"  # "Hello World!!!!!" in hextry:# 加密测试ciphertext = sm4_crypto.encrypt(test_key, test_iv, test_plaintext)# 解密测试decrypted = sm4_crypto.decrypt(test_key, test_iv, ciphertext)result = {"status": "success","test_results": {"key": test_key,"iv": test_iv,"original_plaintext": test_plaintext,"ciphertext": ciphertext,"decrypted_plaintext": decrypted,"test_passed": test_plaintext == decrypted}}except Exception as e:result = {"status": "error","message": f"Test failed: {str(e)}"}print(json.dumps(result))else:result = {"status": "error","message": f"Unknown command: {command}"}print(json.dumps(result))sys.exit(1)if __name__ == "__main__":main()

python/requirements.txt

gmssl==3.2.1

二、更新的DPI C接口

scripts/dpi_wrapper_gmssl.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "svdpi.h"#define BUFFER_SIZE 1024// 解析JSON响应,提取指定字段
static int parse_json_field(const char* json, const char* field, char* value, int max_len) {char search_pattern[64];sprintf(search_pattern, "\"%s\": \"", field);const char* field_start = strstr(json, search_pattern);if (field_start == NULL) {return -1;}field_start += strlen(search_pattern);const char* field_end = strchr(field_start, '"');if (field_end == NULL) {return -1;}int len = field_end - field_start;if (len >= max_len) {return -1;}strncpy(value, field_start, len);value[len] = '\0';return 0;
}// DPI导出函数:调用Python进行SM4加密
extern "C" int sm4_encrypt_dpi(const char* key,const char* iv,const char* plaintext,char* ciphertext
) {char cmd[BUFFER_SIZE];char result[BUFFER_SIZE];char status[32];FILE *fp;// 构建Python命令snprintf(cmd, sizeof(cmd), "cd ../python && python3 sm4_crypto_gmssl.py encrypt %s %s %s 2>&1", key, iv, plaintext);// 执行Python脚本fp = popen(cmd, "r");if (fp == NULL) {printf("Error: Failed to execute Python script\n");return -1;}// 读取完整结果result[0] = '\0';if (fgets(result, sizeof(result), fp) == NULL) {pclose(fp);printf("Error: Failed to read Python output\n");return -1;}pclose(fp);// 检查状态if (parse_json_field(result, "status", status, sizeof(status)) != 0) {printf("Error: Failed to parse status from JSON\n");return -1;}if (strcmp(status, "success") != 0) {char error_msg[256];if (parse_json_field(result, "message", error_msg, sizeof(error_msg)) == 0) {printf("Error from Python: %s\n", error_msg);}return -1;}// 提取密文if (parse_json_field(result, "ciphertext", ciphertext, 64) != 0) {printf("Error: Failed to parse ciphertext from JSON\n");return -1;}return 0;
}// DPI导出函数:调用Python进行SM4解密
extern "C" int sm4_decrypt_dpi(const char* key,const char* iv,const char* ciphertext,char* plaintext
) {char cmd[BUFFER_SIZE];char result[BUFFER_SIZE];char status[32];FILE *fp;// 构建Python命令snprintf(cmd, sizeof(cmd), "cd ../python && python3 sm4_crypto_gmssl.py decrypt %s %s %s 2>&1", key, iv, ciphertext);// 执行Python脚本fp = popen(cmd, "r");if (fp == NULL) {printf("Error: Failed to execute Python script\n");return -1;}// 读取完整结果result[0] = '\0';if (fgets(result, sizeof(result), fp) == NULL) {pclose(fp);printf("Error: Failed to read Python output\n");return -1;}pclose(fp);// 检查状态if (parse_json_field(result, "status", status, sizeof(status)) != 0) {printf("Error: Failed to parse status from JSON\n");return -1;}if (strcmp(status, "success") != 0) {char error_msg[256];if (parse_json_field(result, "message", error_msg, sizeof(error_msg)) == 0) {printf("Error from Python: %s\n", error_msg);}return -1;}// 提取明文if (parse_json_field(result, "plaintext", plaintext, 64) != 0) {printf("Error: Failed to parse plaintext from JSON\n");return -1;}return 0;
}// DPI导出函数:测试Python脚本
extern "C" int sm4_test_dpi() {char cmd[BUFFER_SIZE];char result[BUFFER_SIZE];FILE *fp;// 运行测试命令snprintf(cmd, sizeof(cmd), "cd ../python && python3 sm4_crypto_gmssl.py test 2>&1");fp = popen(cmd, "r");if (fp == NULL) {return -1;}while (fgets(result, sizeof(result), fp) != NULL) {printf("%s", result);}pclose(fp);return 0;
}

三、安装和使用说明

安装gmssl库

# 安装gmssl Python库
pip install gmssl# 或者使用requirements.txt
cd python
pip install -r requirements.txt

测试Python脚本

# 测试脚本功能
cd python
python3 sm4_crypto_gmssl.py test# 手动测试加密
python3 sm4_crypto_gmssl.py encrypt 0123456789abcdef0123456789abcdef fedcba9876543210fedcba9876543210 48656c6c6f20576f726c6421212121# 手动测试解密(使用上面加密的结果)
python3 sm4_crypto_gmssl.py decrypt 0123456789abcdef0123456789abcdef fedcba9876543210fedcba9876543210 <ciphertext_from_above>

四、Makefile更新

# 顶层Makefile# 工具和路径定义
PYTHON = python3
PYTHON_DIR = python
SRC_DIR = src
SCRIPT_DIR = scripts
WORK_DIR = work
LOG_DIR = logs# 编译选项
VCS_FLAGS = -sverilog +acc +vpi -CFLAGS "-I$(VCS_HOME)/include" 
DPI_FLAGS = -LDFLAGS "-Wl,--no-as-needed".PHONY: all clean compile run test_pythonall: test_python compile run# 测试Python环境
test_python:@echo ">>> Testing Python SM4 implementation..."@cd $(PYTHON_DIR) && $(PYTHON) sm4_crypto_gmssl.py test@echo ">>> Python test completed."# 编译DPI和SystemVerilog
compile:@echo ">>> Compiling DPI wrapper..."@mkdir -p $(WORK_DIR)@gcc -fPIC -shared -o $(WORK_DIR)/dpi_wrapper.so \$(SCRIPT_DIR)/dpi_wrapper_gmssl.c \-I$(VCS_HOME)/include@echo ">>> Compiling SystemVerilog..."@vcs $(VCS_FLAGS) $(DPI_FLAGS) \-o $(WORK_DIR)/simv \$(SRC_DIR)/*.sv \$(WORK_DIR)/dpi_wrapper.so@echo ">>> Compilation completed."# 运行仿真
run:@echo ">>> Running simulation..."@mkdir -p $(LOG_DIR)@cd $(WORK_DIR) && ./simv -l ../$(LOG_DIR)/sim.log@echo ">>> Simulation completed."# 清理
clean:@echo ">>> Cleaning..."@rm -rf $(WORK_DIR) $(LOG_DIR) csrc *.daidir ucli.key@echo ">>> Clean completed."

这个使用gmssl库的实现提供了:

  1. 更简洁的SM4加密解密接口
  2. 完整的错误处理和输入验证
  3. JSON格式的输入输出,便于解析
  4. 内置测试功能,确保环境正确配置
  5. 详细的错误信息输出
http://www.xdnf.cn/news/14826.html

相关文章:

  • 动手学深度学习-学习笔记(总)
  • IDEA中application.yml配置文件不自动提示解决办法
  • 运算方法和运算器补充
  • 【AI大模型面试八股文】大模型训练中如何应对灾难性遗忘问题?
  • Swagger 安装使用教程
  • RabbitMQ 4.1.1初体验
  • 一个简单的分布式追踪系统
  • 区块链技术在物联网(IoT)中的核心应用场景
  • 利用TCP协议,创建一个多人聊天室
  • 图灵完备之路(数电学习三分钟)----数据选择器与总线
  • 本地区块链服务在物联网中的应用实例
  • python打卡day58@浙大疏锦行
  • 暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
  • JAVA-springboot 整合Redis
  • Go中使用国家新闻出版署实名认证
  • 【ACP】阿里云云计算高级运维工程师--ACP
  • 硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
  • Docker Desktop 安装到D盘(包括镜像下载等)+ 汉化
  • 7.4_面试_JAVA_
  • css-多条记录,自动换行与自动并行布局及gap兼容
  • linux_git的使用
  • 如何调节笔记本电脑亮度?其实有很多种方式可以调整亮度
  • 深入剖析MYSQL MVCC多版本并发控制+ReadView视图快照规避幻读问题
  • AD7780BRUZ-REEL ADI 24位低功耗ADC转换器 高精度传感器信号链一站式解决方案
  • js中的FileReader对象
  • 指针篇(7)- 指针运算笔试题(阿里巴巴)
  • 计算机科学导论(1)哈佛架构
  • 高功率的照明LN2系列助力电子元件薄膜片检测
  • 二叉树题解——验证二叉搜索树【LeetCode】后序遍历
  • 【狂飙AGI】第8课:AGI-行业大模型(系列2)