首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >无缝互操作:腾讯云KMS在SM2国密算法上与 EasyGmSSL 的兼容实践

无缝互操作:腾讯云KMS在SM2国密算法上与 EasyGmSSL 的兼容实践

作者头像
密码学人CipherHUB
发布2025-06-26 08:37:44
发布2025-06-26 08:37:44
53200
代码可运行
举报
文章被收录于专栏:数安视界数安视界
运行总次数:0
代码可运行

国密算法SM2作为我国自主知识产权的非对称密钥标准,在金融、政务等领域广泛应用。实际开发中,常需本地工具与云服务协同工作,兼容性成为关键痛点。本文通过完整互操作验证,展示EasyGmSSL库与腾讯云KMS在SM2加解密、签名验签上的完美兼容性,特别突出其在极致易用性格式灵活性协议兼容性方面的优势。

一、加解密互操作:云上密钥派生 + 本地解密

场景描述

通过腾讯云KMS生成数据加密密钥(DEK),生成时上传本地SM2公钥到KMS加密DEK,再由本地私钥解密,实现云端和本地端无缝密钥交换。

腾讯云 KMS 在生成数据密钥时,接口中允许传入一把本地的 SM2 公钥。

生成数据密钥的接口会使用这把公钥对数据密钥明文做加密,然后将密文返回,本地使用 SM2 私钥进行解密得到密文,通过这种方式实现信道安全传输,完成安全且合规的密钥交换。

图片
图片
代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import annotations
import base64
import os
from easy_gmssl import EasySm2EncryptionKey , SM2CipherMode
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.kms.v20190118 import kms_client , models
cred = credential.Credential(os.getenv("CLOUD_SECRET_ID") ,
                             os.getenv("CLOUD_SECRET_KEY"))
client = kms_client.KmsClient(cred , "ap-guangzhou")
try:
    # 生成本地 SM2密钥对
    # 去 KMS-API 侧生成 DEK,并使用本地的 SM2公钥加密 DEK 明文得到 DEK 密文
    with open('test_sm2_public.pem' , 'rb') as f:
        sm2_pub_key_bytes = f.read()
    req = models.GenerateDataKeyRequest()
    req.KeyId = '7bab23ea-1a0e-11ee-a405-52540078f78b'
    req.NumberOfBytes = 32
    req.EncryptionAlgorithm = 'SM2_C1C3C2_ASN1'
    req.EncryptionPublicKey = sm2_pub_key_bytes.decode('utf-8')
    resp = client.GenerateDataKey(req)
    print(resp.to_json_string(indent = 4))
    ####################################################
    # 使用本地的 SM2私钥解密 KMS 返回的 DEK 密文数据
    decrypt_sm2 = EasySm2EncryptionKey()
    decrypt_sm2.load_sm2_private_key('./test_sm2_private.pem' , '12345678')
    cipher = base64.b64decode(resp.Plaintext)
    plain_data = decrypt_sm2.Decrypt(cipher_data = cipher ,
                                     cipher_mode = SM2CipherMode.C1C3C2_ASN1)
    print(f'original dek data: {plain_data}, length: {len(plain_data)}')
except TencentCloudSDKException as err:
    print(err)
图片
图片

二、加解密互操作:本地SM2公钥加密数据 + 云端SM2私钥解密数据

场景描述

本地使用 KMS SM2 公钥加密明文得到密文,KMS 控制台或云 API 使用 SM2 私钥解密密文得到明文,实现云端和本地端无缝明文数据交换。

腾讯云 KMS 的 SM2 解密接口,允许传入格式为 C1C3C2_ASN1 的密文进行解密。

图片
图片

控制台也提供了 SM2 解密的工具,可以快速进行解密验证。

图片
图片

本地使用 EasyGmSSL 和 腾讯云 KMS 进行 SM2 加解密的互通验证。

代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import annotations
import base64
import os
from easy_gmssl import EasySm2EncryptionKey , SM2CipherMode
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.kms.v20190118 import kms_client , models
cred = credential.Credential(os.getenv("CLOUD_SECRET_ID") ,
                             os.getenv("CLOUD_SECRET_KEY"))
client = kms_client.KmsClient(cred , "ap-guangzhou")
try:
    # KMS公钥加密,然后去 KMS 控制台使用私钥解密
    # 密钥 ID:5f6b0824-bbf1-11ee-968e-5254000a5333
    encrypt_sm2 = EasySm2EncryptionKey()
    encrypt_sm2.load_sm2_pub_key('./sm2_encrypt.pem')
    plain = b'hello,world\n'
    ret = encrypt_sm2.Encrypt(plain)
    print(f'using kms sm2 public key to encrypt plain, got cipher in base64: {ret}')
    req = models.AsymmetricSm2DecryptRequest()
    req.KeyId = '5f6b0824-bbf1-11ee-968e-5254000a5333'
    req.Ciphertext = ret
    resp = client.AsymmetricSm2Decrypt(req)
    print(resp.to_json_string(indent = 4) , base64.b64decode(resp.Plaintext) == plain)
    assert base64.b64decode(resp.Plaintext) == plain , 'kms decrypt failed, decrypted data is invalid'
except TencentCloudSDKException as err:
    print(err)
图片
图片

三、签名验签互操作:双模式全兼容

腾讯云 KMS 提供非对称密钥的签名验签云 API 接口

图片
图片
图片
图片

控制台也提供针对消息原文和消息摘要的签名验签工具,用户可以在控制台快速完成签名验签的验证流程。

图片
图片

场景1:原始消息签名(RAW模式)

云端签名 → 本地验签

代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import annotations
import base64
import os
from easy_gmssl import EasySM2VerifyKey , EasySM3Digest , EasySm2Key , SignatureMode
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.kms.v20190118 import kms_client , models
cred = credential.Credential(os.getenv("CLOUD_SECRET_ID") ,
                             os.getenv("CLOUD_SECRET_KEY"))
client = kms_client.KmsClient(cred , "ap-guangzhou")
try:
    plain = os.urandom(2048)
    req = models.SignByAsymmetricKeyRequest()
    req.KeyId = '6b9a11ff-bbf1-11ee-829f-5254007a9eec'
    req.Algorithm = 'SM2DSA'
    req.Message = base64.b64encode(plain).decode('utf-8')
    req.MessageType = 'RAW'
    resp = client.SignByAsymmetricKey(req)
    print(resp.to_json_string(indent = 4))
    signature = resp.Signature
    signature_bytes = base64.b64decode(signature)
    test_verify = EasySM2VerifyKey(pem_public_key_file = './sm2_verify.pem')
    test_verify.UpdateData(plain)
    ret = test_verify.VerifySignature(signature_data = signature_bytes , signature_mode = SignatureMode.RS_ASN1)
    print(f'verify sm2 signature for plain data: {ret}')
except TencentCloudSDKException as err:
    print(err)
原始消息签名运行结果
原始消息签名运行结果

场景2:摘要签名(DIGEST模式)

使用EasyGmSSL进行摘要验签的流程
使用EasyGmSSL进行摘要验签的流程

使用 EasyGmSSL 进行本地摘要验签时的流程

本地摘要 → 云端签名 → 本地验签

代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import annotations
import base64
import os
from easy_gmssl import EasySM2VerifyKey , EasySM3Digest , EasySm2Key , SignatureMode
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.kms.v20190118 import kms_client , models
cred = credential.Credential(os.getenv("CLOUD_SECRET_ID") ,
                             os.getenv("CLOUD_SECRET_KEY"))
client = kms_client.KmsClient(cred , "ap-guangzhou")
try:
    plain = os.urandom(2048)
    h = EasySM3Digest()
    h.UpdateData(plain)
    hash_bytes , hash_len , plain_len = h.GetHash()
    print(f'plain sm3 hash:{base64.b64encode(hash_bytes).decode()}, length:{hash_len}, plain_len:{plain_len}')
    req = models.SignByAsymmetricKeyRequest()
    req.KeyId = '6b9a11ff-bbf1-11ee-829f-5254007a9eec'
    req.Algorithm = 'SM2DSA'
    req.Message = base64.b64encode(hash_bytes).decode('utf-8')
    req.MessageType = 'DIGEST'
    resp = client.SignByAsymmetricKey(req)
    print(resp.to_json_string(indent = 4))
    signature = resp.Signature
    signature_bytes = base64.b64decode(signature)
    verify = EasySm2Key()
    verify.load_sm2_pub_key('./sm2_verify.pem')
    ret = verify.verify_digest_signature(hash_bytes , signature_bytes)
    print(f'verify sm2 digest signature for plain sm3 hash: {ret}')
except TencentCloudSDKException as err:
    print(err)
摘要消息签名运行结果
摘要消息签名运行结果

双模式全支持

  • RAW模式:直接处理原始数据
  • DIGEST模式:无缝对接SM3摘要

四、关于EasyGmSSL的易用性

安装简单

pip install easy_gmssl

MacOS/Linux安装一条命令搞定。

密文格式灵活转换

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

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

SM2密文格式全支持
SM2密文格式全支持
代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import annotations
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公钥、私钥十六进制简单读取

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

代码语言:javascript
代码运行次数: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())
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 bowenerchen 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、加解密互操作:云上密钥派生 + 本地解密
    • 场景描述
  • 二、加解密互操作:本地SM2公钥加密数据 + 云端SM2私钥解密数据
    • 场景描述
  • 三、签名验签互操作:双模式全兼容
    • 场景1:原始消息签名(RAW模式)
    • 场景2:摘要签名(DIGEST模式)
    • 使用 EasyGmSSL 进行本地摘要验签时的流程
  • 四、关于EasyGmSSL的易用性
    • 安装简单
    • 密文格式灵活转换
    • SM2公钥、私钥十六进制简单读取
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档