国密gmssl介绍(SM2、SM3、SM4算法)
介绍
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。目前SM1算法没有公开,只能集成在芯片中。目前应用较多的是SM2、SM3和SM4算法,这三者用法不一。
SM2属于非对称加密算法,使用公钥加密,私钥解密,在安全性和运算速度方面要优于RSA算法。
SM3属于不可逆加密算法,类似于md5,常用于签名。
SM4属于对称加密算法,可用于替代DES/AES
等国际算法, SM4算法与AES算法具有相同的密钥长度和分组长度,都是128位。
下面以py3来记录这几种算法的使用。
GmSSL
GmSSL是一个开源的加密包的python实现,支持SM2/SM3/SM4等国密(国家商用密码)算法、项目采用对商业应用友好的类BSD开源许可证,开源且可以用于闭源的商业应用。
SM2
介绍
SM2公钥加密算法国密公钥加密标准之一,由国家密码管理局与2010年12月公布。
SM2公钥加密适用于加密长度较短的数据,如会话密钥和消息报文。SM2公钥加密不仅对数据加密,还提供防篡改的特性,即被篡改的或伪造的密文可以在解密的过程中被检查发现,因此通过SM2公钥加密的消息无需格外的校验机制。消息经过SM2公钥加密后长度会增加不到100字节的长度,加密方在准备缓冲区时需要加以留意。
sm2可以使用openssl1.1.1+来生成,也可以直接在线生成。目前的centos一般搭配的openssl1.0.2,如果要使用openssl生成的话,需要先升级,升级方法参考另一篇文章。
这里推荐直接使用现成网站生成,简单方便,可以查看最后一节相关链接。
[root@node-21-243 deploy]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
初始化
from gmssl import sm2, func
# 私钥
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
# 公钥
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
# 声明一个sm2对象
sm2_crypt = sm2.CryptSM2(
public_key=public_key, private_key=private_key)
加解密
# 消息体
data = b"111"
# 加密
enc_data = sm2_crypt.encrypt(data)
# 解密
dec_data =sm2_crypt.decrypt(enc_data)
# 断言解密之后得到原消息体
assert dec_data == data
签名与校验
# 消息体
data = b"111"
# 随机16进制字符串
random_hex_str = func.random_hex(sm2_crypt.para_len)
# 签名
sign = sm2_crypt.sign(data, random_hex_str) # 16进制
# 校验
assert sm2_crypt.verify(sign, data)
sm3签名与校验
# 消息体
data = b"111" # bytes类型
# 调用sm3签名
sign = sm2_crypt.sign_with_sm3(data) # 16进制
# sm3校验签名
assert sm2_crypt.verify_with_sm3(sign, data)
SM3
SM3是国密密码杂凑算法标准,由国家密码管理局于2010年12月公布。SM3的输出杂凑值长度为256比特(32字节),与国际标准SHA-256等长。SM3设计安全性为128比特,安全性与256比特椭圆曲线/SM2、SM4/SMS4、AES-128等同。
sm3算法主要应用于消息体签名,前面介绍SM2的源码时,介绍了一种签名于校验的方法。
from gmssl import sm3, func
# 消息体
data = b'1234'
# sm3 hash算法,可用于签名消息体
print(sm3.sm3_hash(func.bytes_to_list(data)))
SM4
SMS4是我国无线局域网标准WAPI中所采用的分组密码标准,随后被我国商用密码标准采用,又名SM4。
初始化
from gmssl.sm4 import CryptSM4
# 密钥
key = b'3l5butlj26hvv313'
# 消息体
value = b'111' # bytes类型
# 初始化
crypt_sm4 = CryptSM4()
ECB模式
from gmssl.sm4 import SM4_DECRYPT, SM4_ENCRYPT
# 设置密钥与 方法(加密)
crypt_sm4.set_key(key, SM4_ENCRYPT)
# 按设置 将消息体加密
encrypt_value = crypt_sm4.crypt_ecb(value) # bytes类型
# 设置密钥与 方法(解密)
crypt_sm4.set_key(key, SM4_DECRYPT)
# 按设置将密文 解密
decrypt_value = crypt_sm4.crypt_ecb(encrypt_value) # bytes类型
# 断言 解密得到原消息体
assert value == decrypt_value
CBC模式
from gmssl.sm4 import SM4_DECRYPT, SM4_ENCRYPT
# 填充数据
iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
crypt_sm4.set_key(key, SM4_ENCRYPT)
encrypt_value = crypt_sm4.crypt_cbc(iv , value) # bytes类型
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypt_value = crypt_sm4.crypt_cbc(iv , encrypt_value) # bytes类型
assert value == decrypt_value
相关链接
在线生成sm2公钥私钥:
https://const.net.cn/tool/sm2/genkey/
在线加密链接:
https://the-x.cn/cryptography/Des.aspx
gmssl官方网址: