Python3简单实现与Java的Hutool库SM2的加解密互通

1、背景:

因业务需求,需要与某平台接口对接。平台是Java基于Hutool库实现的SM2加密解密,研究了下SM2的加解密算法,网上找的资料,都是说SM2【椭圆曲线】 公钥长【x,y分量 64字节】,私钥短【32字节】;而平台给的Hutool生成的密钥对,私钥反而比公钥更长,直接用Pyhton做SM2加解密,难以实现数据的互通。后多方查找资料,几经测试终于弄成,其他编程语言亦可参考,现分享如下。

2、密钥分析:

主要参考资料,引用自:https://juejin.cn/post/6981721907653509128

公钥转码分析:

私钥转码分析:

加解密注意事项:

Python Demo 代码:

#!/usr/bin/python3
#coding=utf-8#用Python实现与Java Hutool库  SM2加密、解密 互通
#重要参考资料 引用 https://juejin.cn/post/6981721907653509128from gmssl import sm2
from base64 import b64encode, b64decode
import requests# 常量定义 用Java Hutool库 实现的SM2加密、解密的接口 【密钥格式:Base64, 密文格式:Hex字符串,大写】
JAVA_HUTOOL_ENCRYPT_URL = 'http://127.0.0.1:8384/publicKeyEncrypt'
JAVA_HUTOOL_DECRYPT_URL = 'http://127.0.0.1:8384/privateKeyDecrypt'def sm2_key_pair_java_hutool_to_python(public_sm2_key_base64, private_sm2_key_base64):"""将Java Hutool生成的SM2公钥和私钥转换为Python中使用的格式Args:public_sm2_key_base64 (str): Java Hutool生成的SM2公钥的Base64编码字符串private_sm2_key_base64 (str): Java Hutool生成的SM2私钥的Base64编码字符串Returns:tuple: 包含两个元素的元组,分别为:- str: 截取后的SM2公钥(大写的Hex字符串)- str: 截取后的SM2私钥(大写的Hex字符串)"""public_sm2_key_bin = b64decode(public_sm2_key_base64)private_sm2_key_bin = b64decode(private_sm2_key_base64)public_sm2_key_hex = ''.join(format(x, '02X') for x in public_sm2_key_bin)private_sm2_key_hex = ''.join(format(x, '02X') for x in private_sm2_key_bin)sm2_public_key = public_sm2_key_hex[-128:]sm2_private_key = private_sm2_key_hex[72:72+64]return sm2_public_key, sm2_private_keydef encrypt(message, sm2_crypt):"""使用SM2加密消息Args:message (str): 要加密的消息sm2_crypt (sm2.CryptSM2): SM2加密对象Returns:str: 加密后的Hex字符串"""try:byte_array = sm2_crypt.encrypt(message.encode(encoding="utf-8"))encode_info = '04' + ''.join(format(x, '02X') for x in byte_array)return encode_infoexcept Exception as e:print(f"Encryption error: {e}")return Nonedef decrypt(hex_string, sm2_crypt):"""使用SM2解密Hex字符串Args:hex_string (str): 要解密的Hex字符串sm2_crypt (sm2.CryptSM2): SM2加密对象Returns:str: 解密后的明文信息"""try:if hex_string.startswith("04"):hex_string = hex_string[2:]byte_array = bytes.fromhex(hex_string)decode_info = sm2_crypt.decrypt(byte_array).decode(encoding="utf-8")return decode_infoexcept Exception as e:print(f"Decryption error: {e}")return Nonedef encrypt_java_hutool(message, public_key_base64):"""使用Java Hutool加密消息Args:message (str): 要加密的消息public_key_base64 (str): Java Hutool生成的公钥的Base64编码字符串Returns:str: 加密后的字符串"""try:data = {'publicKey': public_key_base64,'plainTxt': message}response = requests.post(url=JAVA_HUTOOL_ENCRYPT_URL, data=data)return response.json()['data']except Exception as e:print(f"Java Hutool Encryption error: {e}")return Nonedef decrypt_java_hutool(cipher, private_key_base64):"""使用Java Hutool解密消息Args:cipher (str): 要解密的Hex字符串private_key_base64 (str): Java Hutool生成的私钥的Base64编码字符串Returns:str: 解密后的明文信息"""try:data = {'privateKey': private_key_base64,'ciphertext': cipher}response = requests.post(url=JAVA_HUTOOL_DECRYPT_URL, data=data)return response.json()['data']except Exception as e:print(f"Java Hutool Decryption error: {e}")return Noneif __name__ == "__main__":# JavaHutool 生成的公钥私钥对public_sm2_key_base64 = 'MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAErcXffRE7psQ7xTkrxEBzH3VQVviZ/pd1HBDFTfUwOmqx5n4zNjqJfDzS7yvFCfAmehoejdeE2UTecJgb72dtDQ=='private_sm2_key_base64 = 'MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgXFpB6hO0RjwT7UhFkqBX85/hclTf45nPZ8ljuANGTu+gCgYIKoEcz1UBgi2hRANCAAStxd99ETumxDvFOSvEQHMfdVBW+Jn+l3UcEMVN9TA6arHmfjM2Ool8PNLvK8UJ8CZ6Gh6N14TZRN5wmBvvZ20N'sm2_public_key, sm2_private_key = sm2_key_pair_java_hutool_to_python(public_sm2_key_base64, private_sm2_key_base64)sm2_crypt = sm2.CryptSM2(public_key=sm2_public_key, private_key=sm2_private_key)message = "呵呵呵1234567890123abc"print("原始内容为: " + message)cipher = encrypt(message, sm2_crypt)print("Python加密结果为: " + cipher)java_hutool_message = decrypt_java_hutool(cipher, private_sm2_key_base64)print("Java Hutool解密结果为: " + java_hutool_message)java_hutool_cipher = encrypt_java_hutool(message, public_sm2_key_base64)print("Java Hutool加密结果为: " + java_hutool_cipher)python_message = decrypt(java_hutool_cipher, sm2_crypt)print("Python解密结果为: " + python_message)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/32028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为---OSPF被动接口配置(四)

9.4 OSPF被动接口配置 9.4.1 原理概述 OSPF被动接口也称抑制接口,成为被动接口后,将不会接收和发送OSPF报文。如果要使OSPF路由信息不被某一网络中的路由器获得且使本地路由器不接收网络中其他路由器发布的路由更新信息,即已运行在OSPF协议…

FuTalk设计周刊-Vol.031

🔥AI漫谈 热点捕手 1、如何用自然语言 5 分钟构建个人知识库应用?我的 GPTs builder 尝试 开发者的想象力闸门一旦打开,迎接我们的必然是目不暇接的 AI 应用浪潮冲击。 链接https://sspai.com/post/84325 2、GPT-4 Turbo、功能融合&#x…

Android的OverlayFS原理与作用

标签: OverlayFS; Android;Overlay Filesystem; Android的OverlayFS原理与作用 概述 OverlayFS(Overlay Filesystem)是一种联合文件系统,允许将一个或多个文件系统叠加在一起,使它们表现为一个单一的文件系统。Android系统利用OverlayFS来实现动态文件系统的叠加和管…

Java延迟初始化Logger日志对象

开源项目SDK:https://github.com/mingyang66/spring-parent 个人文档:https://mingyang66.github.io/raccoon-docs/#/ 将日志Logger对象定义在静态内部类中是一种常见的做法,这样做是有它特殊的好处,示例如下: privat…

MDPI期刊汇总(AI方向)

前言 本blog统计了计算机和工程领域的期刊,常见分区包括三种,中科院分区,JCR分区,CiteScore分区,下面分别介绍这三种分区的区别: 1. 中科院分区 中科院分区是中国科学院发布的期刊评价体系,涵…

【机器学习】大模型驱动下的医疗诊断应用

摘要: 随着科技的不断发展,机器学习在医疗领域的应用日益广泛。特别是在大模型的驱动下,机器学习为医疗诊断带来了革命性的变化。本文详细探讨了机器学习在医疗诊断中的应用,包括疾病预测、图像识别、基因分析等方面,并…

Qt 技术博客:深入理解 Qt 中的 delete 和 deleteLater 与信号槽机制

在 Qt 开发中,内存管理和对象生命周期的处理是至关重要的一环。特别是在涉及信号和槽机制时,如何正确删除对象会直接影响应用程序的稳定性。本文将详细讨论在使用 Qt 的信号和槽机制时,delete 和 deleteLater 的工作原理,并给出最…

IOS Swift 从入门到精通: For 循环, While 循环, 重复循环, 退出循环, 退出多重循环, 跳过项目, 无限循环

文章目录 For 循环While 循环重复循环退出循环退出多重循环跳过项目无限循环总结 For 循环 Swift 有几种编写循环的方法,但它们的底层机制是相同的:重复运行一些代码,直到条件计算为假。 Swift 中最常见的循环是一个for循环:它将…

LCR 142.训练计划IV

1.题目要求: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ int compare(const void* a,const void* b) {return (*(int*)a - *(int*)b); } struct ListNode* trainningPlan(struct ListNode* l1, struct Li…

【数据结构】第十九弹---C语言实现冒泡排序算法

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、冒泡排序基本思想 2、代码的初步实现 3、代码的优化 4、代码的测试 5、时空复杂度分析 6、模拟实现qsort 6.1、冒泡排序函数 6.2、交换数…

针对 AI 优化数据湖仓一体:使用 MinIO 仔细了解 RisingWave

RisingWave 是现代数据湖仓一体处理层中的开源流数据库,专为性能和可扩展性而构建。RisingWave 旨在允许开发人员在流数据上运行 SQL。鉴于 SQL 是数据工程的通用语言,此功能非常重要。它具有强大的架构,包括计算节点、元节点和压缩器节点&am…

分享一个 Fail2ban 过滤规则

今天明月给大家分享个 Fail2ban 的过滤(Filter)规则,有关 Fail2ban 的文章大家可以参考【服务器全面使用 Fail2Ban 初见成效】和【使用 Fail2ban 禁止垃圾采集爬虫,保护 Nginx 服务器】等文了解,总之 Fail2ban 是 Linu…

分流井设备的监测控制和智慧运维

分流井是一种用于将雨水和污水进行分离的设施,通常设置在雨水管和污水管的汇合处。它可以根据不同的情况,将雨水和污水分别排放到不同的管道中,从而实现雨污分流的目的。 以下是一些常见的分流井类型和工作原理: 1、智能分流井&a…

java-SpringBoot执行定时任务-任务调度-@EnableScheduling和@Scheduled

文章目录 java借助springBoot框架,执行定时任务0. 项目地址1. 需求分析2、新建springBoot项目3. 编写定时任务3.1 开启调度任务3.2 编写定时任务方法 java借助springBoot框架,执行定时任务 0. 项目地址 https://github.com/OrangeHza/JavaDemo 1. 需求…

Elasticsearch bool 查询:组合多个查询(must, should, must_not)

在Elasticsearch中,bool查询是一种强大的工具,它允许我们将多个查询子句组合在一起,以实现复杂的搜索逻辑。通过使用must、should和must_not等子句,我们可以构建出精确且灵活的查询语句,以满足各种搜索需求。本文将详细…

Redis小对象压缩

小对象压缩存储 如果Redis内部管理的集合数据结构很小,他会使用紧凑存储形式压缩存储。 Redis的ziplist是一个紧凑的字节数组结构,如下图所示,每个元素之间都是紧挨着的。 如果他存储的是hash结构,那么key和value会作为两个ent…

竞赛 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

supervisor进程管理

supervisor简介 一个python开发的进程管理工具 支持Linux、Unix系统,不支持Windows系统 能将一个普通的命令行进程变为后台deamon,并监控进程状态,异常退出时能自动重启。 supervisor安装 先安装seuptools模块(包管理工具&…

Maven添加reactor依赖失败

目录 情况说明 解决过程 情况说明 起初是自己在学spring boot3&#xff0c;结果到了reactor这一部分的时候&#xff0c;在项目的pom.xml文件中添加下列依赖报错&#xff1a; <dependencyManagement><dependencies><dependency><groupId>io.projectr…

[Django学习]如何在Django中声明“事务”(包括事务回滚)

一、事务概念 事务(transaction)是访问并可能操作各种数据项的一个数据库操作序列&#xff0c;这些操作要么全部执行,要么全部不执行&#xff0c;是一个不可分割的工作单位。比如某软件的转账功能&#xff1a;现在用户A要给B转账300块&#xff0c;其流程为&#xff0c;先检查A的…