國密算法


介紹

國密即國家密碼局認定的國產密碼算法。主要有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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM