有勇气的牛排博客

深入理解 SM2、SM3 和 SM4 国密加密算法:Python 实现案例解析

有勇气的牛排 4084 Python 2024-10-07 16:56:35

1 前言

SM2、SM3、SM4 是中国国家密码管理局发布的商用密码算法,广泛用于国家标准的密码系统中。

关于应用场景:不绝对,可以根据使用需要选择加密算法。

1.1 SM国密算法场景

侧重点:

SM2 主要用于加密和签名。(SM2加密可逆)

SM3 主要用于数据完整性校验。(SM3加密不可逆,类似于md5)

SM4 侧重于数据加密。(SM4加密可逆)

具体场景:

SM2: 数据加密、数字签名、安全通信、身份验证、证书管理、区块链技术。

SM3: 数据完整性验证、数字签名、密码存储、区块链和加密货币、文件指纹。

SM4: 数据加密、网络安全、信息存储、移动设备和物联网、电子支付和金融服务。

通常可以结合使用。

2 SM2 椭圆曲线公钥密码算法

SM2 是基于椭圆曲线的公钥密码算法,类似于国际标准的ECC(Elliptic Curve Cryptography) 算法。

场景:密钥交换、数字签名、公钥加密等。

2.1 数据加密

公钥加密,私钥解密。

SM2 可以用于加密敏感数据,如个人信息、财务数据等。在传输数据时,可以使用接收方的公钥对数据进行加密,确保只有拥有相应私钥的接收方可以解密和访问原始数据。

具体个人信息场景:手机号、身份证等

2.2 数字签名

SM2 不仅可以用于加密数据,还可以用于数字签名。发送方使用私钥对数据进行签名,接收方可以使用发送方的公钥验证签名的真实性。这确保了数据的完整性和来源的可靠性。

2.3 安全通信

具体场景:在线支付、金融交易。

在需要安全通信的场景中(如在线支付、金融交易等),SM2 可以用于建立安全的通信通道,保护数据在传输过程中的安全性。

2.4 身份验证

SM2 可以用于身份验证,确保只有授权用户能够访问特定资源或服务。通过公钥加密挑战消息,只有拥有相应私钥的用户才能解密并响应,确认其身份。

2.5 证书管理

在 PKI(公钥基础设施)中,生成和管理数字证书,以验证公钥的所有者身份。

2.6 区块链技术

用于加密交易数据和身份信息,确保区块链参与者之间的数据交换安全可靠。

3 SM3 哈希算法

SM3是一种安全哈希算法,类似于国际上的 SHA-256。

场景:数据完整性验证、数字签名等

3.1 数据完整性验证

在传输或存储数据时,可以使用 SM3 计算数据的哈希值。接收方可以通过对接收到的数据重新计算哈希值并与原哈希值进行比较,以验证数据是否在传输过程中被篡改。

3.2 数字签名

在数字签名过程中,通常会先对待签名的数据计算哈希值,然后用私钥对哈希值进行签名。接收方通过用公钥解密签名,并重新计算数据的哈希值,以验证签名的真实性和数据的完整性。

与 SM2 一起使用,生成消息摘要,用于对数据进行数字签名。

3.3 密码存储

在用户注册或更改密码时,可以使用 SM3 哈希用户的密码并将哈希值存储在数据库中。当用户登录时,通过计算输入密码的哈希值并与存储的哈希值进行比较,从而验证用户身份。由于 SM3 是不可逆的,攻击者无法从存储的哈希值恢复原始密码。

3.4 区块链和加密货币

区块链中,每个区块都包含前一个区块的哈希值,从而形成一个链。SM3 可以用于计算区块的哈希,确保数据的不可篡改性和完整性。

在区块链技术中,SM3 用于计算区块哈希,确保区块链数据的完整性和安全性。

3.5 文件指纹/文件和数据认证

对于大文件,可以使用 SM3 生成文件的指纹(哈希值),以便在后续操作中快速比较文件是否相同,而不需要比较整个文件内容。

用于文件的哈希校验,确保文件在传输或存储过程中的安全性。

4 SM4 是一种分组对称算法

SM4是一种分组对称加密算法,类似于国际标准的 AES (Advanced Encryption Standard),它使用128位密钥进行数据加密。

场景:无线网络安全等。

4.1 数据加密

用于加密数据(如文件、消息等)以保护敏感信息,适用于存储和传输。

4.2 网络安全

在 VPN(虚拟专用网络)、SSL/TLS 等网络安全协议中,确保数据传输的安全性。

4.3 信息存储

用于数据库加密和文件系统加密,保护存储在磁盘上的敏感数据。

4.4 移动设备和物联网

适用于移动设备和 IoT 设备中的数据保护,确保数据在设备间传输时的安全性。

4.5 电子支付和金融服务

在金融行业中,确保交易数据的安全性和保密性。

5 Python 实战案例

测试环境:Python3.10.9

pip install gmssl==3.2.2

5.1 SM2 算法

深入理解 SM2、SM3 和 SM4 国密加密算法:Python 实现案例解析

SM2算法可逆。

场景:手机、身份证号等必要时间可以查询的。

from gmssl import sm2 # 16 进制的公钥和私钥 private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5' public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207' # 待加密中文字符串 text = "有勇氣的牛排 www.couragesteak.com" print("原始數據:", text) # 初始化 SM2 对象 sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key, asn1=False) # 加密数据 data = text.encode('utf-8') # 将字符串转换为字节 enc_data = sm2_crypt.encrypt(data) # 进行加密 print("加密數據: ", enc_data) # 解密数据 decrypted_data = sm2_crypt.decrypt(enc_data) # 直接使用加密数据进行解密 print("解密后數據:", decrypted_data.decode('utf-8')) # 将解密后的数据解码为字符串

Python SM2算法

5.2 SM3 算法

SM3 哈希算法是不可逆的。

from gmssl import sm3, func def compute_sm3_hash(data: str) -> str: """ 计算字符串的 SM3 哈希值 :param data: 输入字符串 :return: SM3 哈希值 (16 进制字符串) """ # 将字符串编码为字节 data_bytes = data.encode('utf-8') # 计算 SM3 哈希 hash_value = sm3.sm3_hash(func.bytes_to_list(data_bytes)) return hash_value if __name__ == "__main__": # 示例输入 input_data = "有勇氣的牛排 www.couragesteak.com" sm3_hash = compute_sm3_hash(input_data) print("输入数据:", input_data) print("SM3 哈希值:", sm3_hash)

Python SM3算法

5.3 SM4 算法

# -*- coding:utf-8 -*- # @Author: 有勇气的牛排 # 博客地址: https://www.couragesteak.com # @FileName : util_sm4.py # @desc : SM4 加密算法 # 场景:数据加密、网络安全、信息存储、移动设备和物联网、电子支付和金融服务。 from gmssl import sm4 class SM4Crypt: def __init__(self, key: bytes, mode: str = 'ECB'): """ 初始化 SM4 加密/解密对象 :param key: 加密密钥(16 字节长度) :param mode: 加密模式('ECB' 或 'CBC') """ self.key = key self.mode = mode if mode == 'ECB': self.sm4_crypt = sm4.CryptSM4(mode=sm4.SM4_ENCRYPT) elif mode == 'CBC': self.sm4_crypt = sm4.CryptSM4(mode=sm4.SM4_DECRYPT) def encrypt(self, data: bytes) -> bytes: """ 加密数据 :param data: 待加密的字节数据 :return: 加密后的字节数据 """ self.sm4_crypt.set_key(self.key, sm4.SM4_ENCRYPT) encrypted_data = self.sm4_crypt.crypt_ecb(data) if self.mode == 'ECB' else self.sm4_crypt.crypt_cbc(data) return encrypted_data def decrypt(self, enc_data: bytes) -> bytes: """ 解密数据 :param enc_data: 加密后的字节数据 :return: 解密后的字节数据 """ self.sm4_crypt.set_key(self.key, sm4.SM4_DECRYPT) decrypted_data = self.sm4_crypt.crypt_ecb(enc_data) if self.mode == 'ECB' else self.sm4_crypt.crypt_cbc( enc_data) return decrypted_data if __name__ == "__main__": # SM4 密钥,必须是 16 字节(128 位) key = b'0123456789abcdef' # 待加密的数据 user_data = "有勇氣的牛排 www.couragesteak.com" print("原始数据:", user_data) # 初始化 SM4 加密类 sm4_util = SM4Crypt(key=key, mode='ECB') # 加密数据 encrypted_data = sm4_util.encrypt(user_data.encode('utf-8')) print("加密后的数据:", encrypted_data) # 解密数据 decrypted_data = sm4_util.decrypt(encrypted_data) print("解密后的数据:", decrypted_data.decode('utf-8'))

Python SM4算法


留言

有勇气的牛排 2024-12-07 11:19:37
SM国密加密
专栏
文章
加入群聊