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

中国SM系列密码算法的入门教程

SM系列密码算法是中国国家密码管理局(简称“国密局”)制定和发布的一系列商用密码算法标准,旨在保障国家信息安全,构建自主可控的安全体系。这套算法在金融、政府、物联网、区块链等众多领域得到广泛应用。


核心算法概览

SM系列主要包括以下核心算法:

算法名称全称类型对标国际算法简要描述
SM1对称分组密码算法对称加密AES分组长度和密钥长度均为128位。算法不公开,通过硬件芯片实现。
SM2椭圆曲线公钥密码算法非对称加密ECC (ECDSA/ECDH)基于椭圆曲线密码学(ECC),用于数字签名、密钥交换和公钥加密。
SM3密码杂凑算法哈希算法SHA-256输出长度为256位(32字节)的杂凑值。用于数字签名和消息认证。
SM4对称分组密码算法对称加密AES分组长度和密钥长度均为128位。算法公开,软件和硬件均可实现。
SM7分组密码算法对称加密-适用于非接触式IC卡应用,如门禁、一卡通等。
SM9标识密码算法非对称加密-基于标识的密码系统(IBC),用户标识(如邮箱、手机号)即为公钥,简化密钥管理。
ZUC(祖冲之)序列密码算法流加密SNOW 3G主要用于4G/5G移动通信中的国际加密和完整性保护算法。

接下来,我们将重点讲解最常用且算法公开的SM2、SM3、SM4


1. SM2:椭圆曲线公钥密码算法

SM2是基于椭圆曲线密码学(ECC)的公钥算法。相比RSA,在相同安全强度下,ECC所需的密钥长度更短(例如256位SM2约等于3072位RSA),计算更快,带宽占用更小。

核心组件:
  • 椭圆曲线参数: 使用一条特定的椭圆曲线,其方程通常为 $y^2 = x^3 + ax + b$ over $F_p$(素数域)。国密局推荐了一套标准参数(包括素数p、系数a、b、基点G、阶n等)。

  • 密钥对:

    • 私钥(d): 一个在 [1, n-1] 范围内随机选取的整数。

    • 公钥(P): 私钥对应的点,通过计算 $P = d \cdot G$(G的d倍点乘)得到。

三大功能:
  1. 数字签名

    • 签名生成: 对消息M,使用私钥d和SM3哈希算法生成签名(r, s)。

    • 签名验证: 使用公钥P、消息M和签名(r, s)来验证签名的有效性。

  2. 密钥交换

    • 两方(A和B)可以通过交换一些信息,并结合自己的私钥和对方的公钥,协商出一个只有双方才知道的共享密钥(Session Key),用于后续的对称加密通信。

  3. 公钥加密

    • 加密: 使用接收方的公钥P对消息M进行加密,生成密文C。

    • 解密: 接收方使用自己的私钥d对密文C进行解密,恢复出原始消息M。

简单代码示例(使用Python的gmssl库):

from gmssl import sm2, func# 1. 初始化(可以使用默认曲线参数)
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)# 2. 数据加密和解密
data = b"This is the message to be encrypted"
enc_data = sm2_crypt.encrypt(data)
dec_data = sm2_crypt.decrypt(enc_data)
print(f"Decrypted: {dec_data.decode()}")# 3. 数字签名和验证
random_hex_str = func.random_hex(sm2_crypt.para_len)
sign = sm2_crypt.sign(data, random_hex_str)
assert sm2_crypt.verify(sign, data) # 验证成功则无异常

2. SM3:密码杂凑算法

SM3是一种密码学哈希函数,可将任意长度的输入消息压缩成固定长度(256位)的摘要(哈希值)。其设计结构与SHA-256类似,但具体设计存在差异。

  • 特性: 单向性、抗碰撞性、雪崩效应。

  • 应用:

    • 与SM2结合用于数字签名。

    • 生成消息认证码(MAC)。

    • 保护数据完整性。

简单代码示例:

from gmssl import sm3def sm3_hash_bytes(data):"""计算字节数据的SM3哈希值"""return sm3.sm3_hash(list(data))# 测试
data = b"Hello, World! This is SM3."
hash_result = sm3_hash_bytes(data)
print(f"原始数据: {data.decode()}")
print(f"SM3 Hash: {hash_result}")
print(f"哈希长度: {len(hash_result)} 字符")  # SM3输出64个十六进制字符

3. SM4:对称分组密码算法

SM4是一种分组密码算法,用于替代DES/3DES和AES。它采用32轮迭代的非平衡Feistel结构

  • 分组长度: 128位

  • 密钥长度: 128位

  • 模式: 支持ECB、CBC、CFB、OFB、CTR等标准工作模式。

  • 应用: 大量数据的加密,如文件加密、通信信道加密。

加解密过程(以CBC模式为例):

  1. 密钥扩展: 将输入的128位主密钥扩展成32个32位的轮密钥。

  2. 加密(多轮): 每一轮操作包括非线性τ变换、线性变换L、轮异或等。

  3. 解密: 解密算法与加密算法相同,只是轮密钥的使用顺序相反。

简单代码示例:

from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import binasciikey = b'3l5butlj26hvv313' # 16 bytes key
iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # 16 bytes IV for CBC
crypt_sm4 = CryptSM4()# 加密
plaintext = b'This is a secret message'
crypt_sm4.set_key(key, SM4_ENCRYPT)
ciphertext = crypt_sm4.crypt_cbc(iv, plaintext)
print(f"Ciphertext (hex): {binascii.hexlify(ciphertext)}")# 解密
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypted_text = crypt_sm4.crypt_cbc(iv, ciphertext)
print(f"Decrypted: {decrypted_text.decode()}")

总结与学习路径

  1. 理解基础: 首先确保理解对称加密、非对称加密、哈希函数的基本概念。

  2. 从SM3/SM4开始: 它们的应用和概念(如分组、模式)与SHA系列和AES类似,更容易上手。

  3. 攻克SM2: 需要一些椭圆曲线密码学的基础数学知识(有限域、点加、点乘),但使用现有库时可以暂时忽略其复杂实现。

  4. 实践:

    • 使用现有的国密库(如GmSSL、TongSuo)进行编程实践。

    • 尝试实现一个简单的“SM2签名+SM4加密”的数据安全传输流程:

      1. 用SM3对消息取哈希。

      2. 用SM2私钥对哈希值签名。

      3. 生成一个随机的SM4会话密钥。

      4. 用SM4加密原始消息。

      5. 用接收方的SM2公钥加密刚才的SM4会话密钥。

      6. 将签名、加密后的消息、加密后的会话密钥一起发送给对方。

重要资源:

  • 国家密码管理局官网: 查找标准文档(但算法细节通常在标准文本中)。

  • GmSSL项目: 一个开源的密码工具箱,支持SM2/SM3/SM4/SM9等国密算法。(https://github.com/guanzhi/GmSSL)

  • TongSuo(铜锁): 蚂蚁集团开源的密码学库,源自OpenSSL,提供对国密算法的强大支持。(Hello from OpenAtom 铜锁/Tongsuo | OpenAtom 铜锁/Tongsuo)

希望这份教程能帮助您系统地入门中国SM系列密码算法!

http://www.dtcms.com/a/344758.html

相关文章:

  • 网络实践——Socket编程UDP
  • Seaborn数据可视化实战:Seaborn颜色与样式定制教程
  • elasticsearch的使用
  • odoo-065 两个视图中的action类型的button互相引用,造成死循环
  • ubuntu使用fstab挂载USB设备(移动硬盘)
  • Claude Code接入Serena mcp
  • ESP32C5,使用espidf框架配置wifi扫描时报错,为什么会提示,ghz_5_channels的参数无效呢
  • 开发避坑指南(32):FastJSON异常JSONArray cannot be cast to JSONObject解决方案
  • 什么是数据分类分级?数据分类分级技术实现路径及产品推荐
  • ​Kubernetes 详解:云原生时代的容器编排与管理
  • 08.21总结
  • 【yocto】BitBake指令汇总解析
  • 基于springboot的农产品社区配送系统
  • 线性回归的学习
  • C++ unistd.h库文件介绍(文件与目录操作, 进程管理, 系统环境访问, 底层I/O操作, 系统休眠/执行控制)
  • golang 非error错误分类
  • 【如何生成专业级 API 接口文档:从规范到实战】
  • 指针实现数组的逆序存放并输出
  • IKE 与 ISAKMP 核心笔记
  • JCTools Spmc 单生产者-多消费者的无锁并发有界队列
  • 支持轻量化部署的混元3D世界模型Lite版本上线魔乐社区,昇腾部署实践来啦
  • FCT/ATE/ICT通用测试上位机软件
  • Leetcode—595. 大的国家【简单】
  • JUC之Fork/Join
  • WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析9
  • 2-3.Python 编码基础 - 类型检测与类型转换
  • Vue 实现可拖拽分割布局(支持左右、上下拖拽调整)
  • Java 学习笔记(基础篇7)
  • 2025年游戏盾SDK动态加密技术全景解析:从防御破解到重塑游戏安全基石
  • CSM5110 5V/1A降压芯片 SOT23-5封装 可替代RY3408 带OVP保护