前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >简易国密算法 PythonSDK:EasyGmSSL-Python

简易国密算法 PythonSDK:EasyGmSSL-Python

原创
作者头像
bowenerchen
修改2024-12-24 14:40:12
修改2024-12-24 14:40:12
54870
代码可运行
举报
文章被收录于专栏:数安视界
运行总次数:0
代码可运行

EasyGmssl-Python

一、概述

EasyGmSSL FORK 自北京大学 GUNAZHI 老师团队的开源国密算法库GmSSL,EasyGmSSL旨在为开发者提供一套接口更加友好的国密算法应用开发工具。它涵盖了SM2、SM3、SM4等国密算法的核心功能,并针对实际使用场景中的痛点进行了针对性改进。

此 SDK 的 git 地址为:https://github.com/bowenerchen/GmSSL-Python

更详细的示例代码请参考:https://github.com/bowenerchen/GmSSL-Python/tree/main/demo_easy_gmssl

PyPi 项目地址为:https://pypi.org/project/easy-gmssl/

二、特色功能

便捷安装

在通过pip安装本SDK时,具备自动编译底层C库的能力,并且会智能地安装编译好的二进制文件,避免对系统路径造成污染,确保了安装过程的简洁性与独立性,让您无需繁琐的手动配置即可快速上手。

SM2增强功能

SM2 相关能力
SM2 相关能力
密钥加解密模式多样化

新增了多种SM2密钥加解密模式选择,包括C1C3C2、C1C3C2_ASN1、C1C2C3、C1C2C3_ASN1。这些模式为不同应用需求提供了更灵活的加密策略,无论是在对加密效率有要求,还是对加密数据格式兼容性有考量的场景下,都能找到合适的解决方案。

签名验签模式扩展

在SM2签名验签时,增加了RS_ASN1、RS两种模式选择,适应不同的签名规范和验证场景,使签名验签操作更加贴合实际业务需求。

密钥读取便捷化

允许用户轻松读取SM2公钥、私钥的十六进制明文,方便在调试、密钥管理等环节快速获取关键信息,提升开发效率。

基础算法优化

对于SM4和SM3以及随机数生成部分,虽然核心算法基于底层库,但在接口层着重增加了参数说明。这使得即使是初次接触国密算法的开发者,也能迅速理解每个参数的含义与用途,降低了开发门槛,加速项目开发进程。

三、安装指南

只需在命令行中执行以下pip命令即可完成安装:

代码语言:bash
复制
pip install easy_gmssl

安装过程中,系统会自动处理底层C库的编译与安装事宜,待编译安装完成后即可开启国密算法开发之旅。

自动编译安装
自动编译安装
安装好的静态库
安装好的静态库

四、使用示例

SM密钥加解密

输出多种模式下的密文

代码语言:python
代码运行次数:0
复制
from easy_gmssl import EasySm2EncryptionKey, SM2CipherFormat, SM2CipherMode

enc = EasySm2EncryptionKey()
plain = 'hello,world'
# 遍历当前支持的所有 SM2 加解密算法模式
# 当前支持的模式包括:
# C1C3C2_ASN1、C1C3C2、C1C2C3_ASN1、C1C2C3
for mode in SM2CipherMode:
    print(mode, '密文 in Hex:', enc.Encrypt('hello,world'.encode('utf-8'), mode, SM2CipherFormat.HexStr))
各种模式下的密文
各种模式下的密文

SM2公钥、私钥读取

代码语言:python
代码运行次数:0
复制
from __future__ import annotations
   
from easy_gmssl import EasySm2Key
   
test = EasySm2Key()
print('公钥数据 In Hex:', test.get_sm2_public_key_in_hex())
print('私钥数据 In Hex:', test.get_sm2_private_key_in_hex())
读取公私钥十六进制数据
读取公私钥十六进制数据

SM2签名验签

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import random

from easy_gmssl import EasySM2SignKey, EasySM2VerifyKey, SignatureMode

signer_id = 'test_signer'
print('signer_id hex:', signer_id.encode('utf-8').hex())
# 初始化用于签名验签的 SM2 密钥,此时不需要关心签名值的模式
test = EasySM2SignKey(signer_id = signer_id, pem_private_key_file = './test_keys/tmp_test_sm2_private.pem',
                      password = '123456')
plain = bytes([random.randint(0, 255) for _ in range(0, 64)])
print('plain hex:', plain.hex())
print('private key hex:', test.get_sm2_private_key_in_hex())
print('public key hex:', test.get_sm2_public_key_in_hex())

# 计算签名
test.UpdateData(plain)
# 指定签名值模式为 RS 模式,可选 RS、RS_ASN1
sign_value = test.GetSignValue(signature_mode = SignatureMode.RS)
print('signature hex:', sign_value.hex())

# 初始化用于验证签名的 SM2 密钥
verify_test = EasySM2VerifyKey(signer_id = signer_id, pem_public_key_file = './test_keys/tmp_test_sm2_public.pem')
# 验证签名
verify_test.UpdateData(plain)
# 验证签名时同样指定签名值格式为 RS 模式
ret = verify_test.VerifySignature(sign_value, signature_mode = SignatureMode.RS)
签名验签
签名验签

SM4对称加解密示例

CBC模式
代码语言:python
代码运行次数:0
复制
from __future__ import annotations

from easy_gmssl import EasySm4CBC
from easy_gmssl.gmssl import SM4_BLOCK_SIZE, SM4_CBC_IV_SIZE

key = 'x' * SM4_BLOCK_SIZE
iv = 'y' * SM4_CBC_IV_SIZE
# 加密操作
test_cbc_enc = EasySm4CBC(key.encode('utf-8'), iv.encode('utf-8'), True)
plain1 = 'hello,world'
plain2 = '1234567890'
cipher1 = test_cbc_enc.Update(plain1.encode('utf-8'))
cipher2 = test_cbc_enc.Update(plain2.encode('utf-8'))
ciphers = cipher1 + cipher2 + test_cbc_enc.Finish()

# 解密操作
test_dec = EasySm4CBC(key.encode('utf-8'), iv.encode('utf-8'), False)
decrypted_plain1 = test_dec.Update(ciphers)
decrypted_plain = decrypted_plain1 + test_dec.Finish()

print('解密成功:', decrypted_plain == (plain1 + plain2).encode('utf-8'))
GCM模式
代码语言:python
代码运行次数:0
复制
from __future__ import annotations

from easy_gmssl import EasySm4GCM
from easy_gmssl.gmssl import SM4_BLOCK_SIZE, SM4_CBC_IV_SIZE, SM4_GCM_DEFAULT_TAG_SIZE

key = 'x' * SM4_BLOCK_SIZE
iv = 'y' * SM4_CBC_IV_SIZE
# 定义拓展验证数据,加解密时此数据需要保持一致
aad = 'a' * (SM4_BLOCK_SIZE + SM4_CBC_IV_SIZE)
# 定义tag长度,最小 8 个字节
tag_len = int(SM4_GCM_DEFAULT_TAG_SIZE / 2)
test_gcm_enc = EasySm4GCM(key.encode('utf-8'), iv.encode('utf-8'), aad, tag_len, True)
plain1 = 'hello,world'
plain2 = '1234567890'
# 进行加密操作
cipher1 = test_gcm_enc.Update(plain1.encode('utf-8'))
cipher2 = test_gcm_enc.Update(plain2.encode('utf-8'))
ciphers = cipher1 + cipher2 + test_gcm_enc.Finish()
# GCM模式下的密文长度与明文长度等长
# 返回的密文中包含了 tag 长度
print('ciphers len:', len(ciphers), 'tag_len=', tag_len, 'plain len:', len(plain1 + plain2))

# 进行解密操作,此时aad和tag_len需要与加密时保持一致
test_dec = EasySm4GCM(key.encode('utf-8'), iv.encode('utf-8'), aad, tag_len, False)
decrypted_plain1 = test_dec.Update(ciphers)
decrypted_plain = decrypted_plain1 + test_dec.Finish()

print('解密成功:', decrypted_plain == (plain1 + plain2).encode('utf-8'))

SM3 HASH 与 HMAC 示例

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import random

from easy_gmssl import EasySM3Digest, EasySM3Hmac
from easy_gmssl.gmssl import SM3_HMAC_MAX_KEY_SIZE

test = EasySM3Digest()
# 计算哈希
plain1 = 'hello,world'.encode('utf-8')
plain2 = '1234567890'.encode('utf-8')
plain3 = (plain1 + plain2)
print('plain hex:', plain3.hex())
test.UpdateData(plain3)
hash_value_2, hash_len, length2 = test.GetHash()
print('hash value:', hash_value_2.hex())
print('hash value length in bytes:', hash_len)

# 计算HMAC
plain = 'hello,world'.encode('utf-8')
print('plain hex:', plain.hex())
key = bytes([random.randint(0, 255) for _ in range(0, SM3_HMAC_MAX_KEY_SIZE)])
print('key hex:', key.hex())
test = EasySM3Hmac(key)
test.UpdateData(plain)
hmac_hex, hmac_len, plain_len = test.GetHmac()
print('hmac value:', hmac_hex.hex(), 'hmac len:', hmac_len, 'plain len:', plain_len)
计算 HASH 与 HMAC
计算 HASH 与 HMAC

随机数生成示例

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

from easy_gmssl import EasyRandomData, RandomMode

# 生成随机字节流
test = EasyRandomData()
ret = test.GetRandomData(20)
print(ret.hex())
# 生成随机字符串
test = EasyRandomData(mode = RandomMode.RandomStr)
ret = test.GetRandomData(64)
print(ret)
生成随机数
生成随机数

ZUC 加解密示例

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

from easy_gmssl import EasyRandomData, EasyZuc
from easy_gmssl.gmssl import ZUC_IV_SIZE, ZUC_KEY_SIZE

# 生成密钥与 IV
key = EasyRandomData().GetRandomData(ZUC_KEY_SIZE)
iv = EasyRandomData().GetRandomData(ZUC_IV_SIZE)
# 加密操作
test = EasyZuc(key, iv)
plain1 = 'hello,world'.encode('utf-8')
cipher1 = test.Update(plain1)
plain2 = '1234567890'.encode('utf-8')
cipher2 = test.Update(plain2)
cipher3 = test.Finish()

# 解密操作
test2 = EasyZuc(key, iv)
ret1 = test2.Update(cipher1)
ret2 = test2.Update(cipher2)
ret3 = test2.Update(cipher3)
ret4 = test2.Finish()
assert ret1 + ret2 + ret3 + ret4 == plain1 + plain2
print('解密成功:', ret1 + ret2 + ret3 + ret4 == plain1 + plain2)

五、注意事项

  1. 在使用SM2密钥加解密、签名验签等功能时,请务必根据实际需求谨慎选择合适的模式,不同模式在数据格式、兼容性等方面存在差异。
  2. 对于读取的公钥、私钥十六进制明文,要妥善保管,防止泄露,因为这是加密体系的核心机密信息。
  3. 虽然SDK尽力优化了接口,但国密算法涉及密码学专业知识,在开发高安全性应用时,建议开发者深入了解相关算法原理,确保应用的安全性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • EasyGmssl-Python
    • 一、概述
    • 二、特色功能
      • 便捷安装
      • SM2增强功能
    • 三、安装指南
    • 四、使用示例
      • SM密钥加解密
      • SM2公钥、私钥读取
      • SM2签名验签
      • SM4对称加解密示例
      • SM3 HASH 与 HMAC 示例
      • 随机数生成示例
      • ZUC 加解密示例
    • 五、注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档