SM4和AES只是加密算法不同,使用起来几乎没有区别,AES相关的例程可以参考:
本文主要介绍SM4加密算法,并提供库里没有的CTR模式模式
特点:
加密过程:
将明文划分为固定大小的块(例如128位)。
对每个块独立使用AES加密算法,使用相同的密钥。
输出得到相应的密文块。
特点:
加密过程:
使用初始化向量(IV)与第一个明文块进行异或运算。
对异或的结果使用AES加密算法,得到第一个密文块。
将第一个密文块作为下一个明文块的IV,继续进行异或和加密。
重复这个过程直到加密完所有的块。
特点:
加密过程:
设计和标准制定
密钥长度
分组长度
轮数
S盒(Substitution Box)
应用领域
国际认可
通过对比这两种算法的设计、应用和性能特征,可以更好地理解它们在不同背景下的使用场景和优势。在选择使用哪种算法时,应考虑特定的安全需求和国际标准。
输出
ECB ENCYRPT(hex): 9a991f25e3303e12173f04f698ed5f4d
ECB DECYRPT(str): 1234567890abcdef
CBC ENCYRPT(hex): d2d68ed9fe06cb40c9a150aa5917f15fa80538810c8117273f53ac7a0735b8f5
CBC DECYRPT(str): 1234567890abcdef123456789abcdef0
CRT ENCYRPT(hex): abab2c11d606092a2e0f6594fb893a2b7aa45f0c5b207da83e4bb3eb754c1f00
CRT DECYRPT(str): 1234567890abcdef123456789abcdef0
源代码
from pysm4 import encrypt_ecb, decrypt_ecb, encrypt_cbc, decrypt_cbc
import base64
sm4_key = "1234567890123456";
sm4_iv = "1234567890abcdef";
sm4_in = "1234567890abcdef123456789abcdef0";
def SM4_CTR(data, key, iv, byteorder = "little"):
'''入参和返回值均为bytes类型'''
i = 0
ret = []
groups_num = len(data) // 16
# bytes 转 int
if byteorder == "little":
iv_int = int.from_bytes(iv[0:4], byteorder)
else:
iv_int = int.from_bytes(iv[12:16], byteorder)
for i in range(groups_num):
temp_bs64 = encrypt_ecb(iv, key)
temp_bytes = base64.b64decode(temp_bs64)
for j in range(16):
ret.append(data[i*16+j] ^ temp_bytes[j])
iv_int += 1
if byteorder == "little":
iv = iv_int.to_bytes(4, byteorder) + iv[4:]
else:
iv = iv[:12] + iv_int.to_bytes(4, byteorder)
if (len(data) % 16):
temp_bs64 = encrypt_ecb(iv, key)
temp_bytes = base64.b64decode(temp_bs64)
for j in range(len(data) % 16):
ret.append(data[i*16+j] ^ temp_bytes[j])
return ret
def ecb_test():
ret = encrypt_ecb(sm4_in.encode(), sm4_key.encode())
print("ECB ENCYRPT(hex): ", base64.b64decode(ret).hex()[:32])
ret = decrypt_ecb(ret, sm4_key.encode())
print("ECB DECYRPT(str): ", ret[:16])
def ccb_test():
ret = encrypt_cbc(sm4_in.encode(), sm4_key.encode(), sm4_iv.encode())
print("CBC ENCYRPT(hex): ", base64.b64decode(ret).hex()[:64])
ret = decrypt_cbc(ret, sm4_key.encode(), sm4_iv.encode())
print("CBC DECYRPT(str): ", ret[:32])
def ctr_test():
ret = SM4_CTR(sm4_in.encode(), sm4_key.encode(), sm4_iv.encode(), "big")
print("CRT ENCYRPT(hex): ", bytes(ret).hex())
ret = SM4_CTR(bytes(ret), sm4_key.encode(), sm4_iv.encode(), "big")
print("CRT DECYRPT(str): ", bytes(ret).decode())
if __name__ == '__main__':
ecb_test()
ccb_test()
ctr_test()