zzzzy09

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

介绍

国密即国家密码局认定的国产密码算法。主要有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官方网址:

http://gmssl.org/

作者:红雨
出处:https://www.cnblogs.com/52why
微信公众号: 红雨python
posted on 2022-04-01 12:55  zzzzy09  阅读(8578)  评论(0编辑  收藏  举报